Optimization suggested by Volker. Don't do a stat system call on normal read path.
[Samba.git] / source3 / smbd / process.c
blobf43005dda3ad8526b5a58b188bb05df69de95095
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/pcap.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"
39 extern bool global_machine_password_needs_changing;
41 static void construct_reply_common(struct smb_request *req, const char *inbuf,
42 char *outbuf);
43 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
45 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
47 bool ok;
49 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
50 return true;
53 sconn->smb1.echo_handler.ref_count++;
55 if (sconn->smb1.echo_handler.ref_count > 1) {
56 return true;
59 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
61 do {
62 ok = fcntl_lock(
63 sconn->smb1.echo_handler.socket_lock_fd,
64 SMB_F_SETLKW, 0, 0, F_WRLCK);
65 } while (!ok && (errno == EINTR));
67 if (!ok) {
68 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
69 return false;
72 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
74 return true;
77 void smbd_lock_socket(struct smbd_server_connection *sconn)
79 if (!smbd_lock_socket_internal(sconn)) {
80 exit_server_cleanly("failed to lock socket");
84 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
86 bool ok;
88 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
89 return true;
92 sconn->smb1.echo_handler.ref_count--;
94 if (sconn->smb1.echo_handler.ref_count > 0) {
95 return true;
98 do {
99 ok = fcntl_lock(
100 sconn->smb1.echo_handler.socket_lock_fd,
101 SMB_F_SETLKW, 0, 0, F_UNLCK);
102 } while (!ok && (errno == EINTR));
104 if (!ok) {
105 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
106 return false;
109 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
111 return true;
114 void smbd_unlock_socket(struct smbd_server_connection *sconn)
116 if (!smbd_unlock_socket_internal(sconn)) {
117 exit_server_cleanly("failed to unlock socket");
121 /* Accessor function for smb_read_error for smbd functions. */
123 /****************************************************************************
124 Send an smb to a fd.
125 ****************************************************************************/
127 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
128 bool do_signing, uint32_t seqnum,
129 bool do_encrypt,
130 struct smb_perfcount_data *pcd)
132 size_t len = 0;
133 size_t nwritten=0;
134 ssize_t ret;
135 char *buf_out = buffer;
137 smbd_lock_socket(sconn);
139 if (do_signing) {
140 /* Sign the outgoing packet if required. */
141 srv_calculate_sign_mac(sconn, buf_out, seqnum);
144 if (do_encrypt) {
145 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
146 if (!NT_STATUS_IS_OK(status)) {
147 DEBUG(0, ("send_smb: SMB encryption failed "
148 "on outgoing packet! Error %s\n",
149 nt_errstr(status) ));
150 goto out;
154 len = smb_len_large(buf_out) + 4;
156 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
157 if (ret <= 0) {
159 char addr[INET6_ADDRSTRLEN];
161 * Try and give an error message saying what
162 * client failed.
164 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
165 (int)sys_getpid(), (int)len,
166 get_peer_addr(sconn->sock, addr, sizeof(addr)),
167 (int)ret, strerror(errno) ));
169 srv_free_enc_buffer(buf_out);
170 goto out;
173 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
174 srv_free_enc_buffer(buf_out);
175 out:
176 SMB_PERFCOUNT_END(pcd);
178 smbd_unlock_socket(sconn);
179 return true;
182 /*******************************************************************
183 Setup the word count and byte count for a smb message.
184 ********************************************************************/
186 int srv_set_message(char *buf,
187 int num_words,
188 int num_bytes,
189 bool zero)
191 if (zero && (num_words || num_bytes)) {
192 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
194 SCVAL(buf,smb_wct,num_words);
195 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
196 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
197 return (smb_size + num_words*2 + num_bytes);
200 static bool valid_smb_header(const uint8_t *inbuf)
202 if (is_encrypted_packet(inbuf)) {
203 return true;
206 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
207 * but it just looks weird to call strncmp for this one.
209 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
212 /* Socket functions for smbd packet processing. */
214 static bool valid_packet_size(size_t len)
217 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
218 * of header. Don't print the error if this fits.... JRA.
221 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
222 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
223 (unsigned long)len));
224 return false;
226 return true;
229 static NTSTATUS read_packet_remainder(int fd, char *buffer,
230 unsigned int timeout, ssize_t len)
232 NTSTATUS status;
234 if (len <= 0) {
235 return NT_STATUS_OK;
238 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
239 if (!NT_STATUS_IS_OK(status)) {
240 char addr[INET6_ADDRSTRLEN];
241 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
242 "error = %s.\n",
243 get_peer_addr(fd, addr, sizeof(addr)),
244 nt_errstr(status)));
246 return status;
249 /****************************************************************************
250 Attempt a zerocopy writeX read. We know here that len > smb_size-4
251 ****************************************************************************/
254 * Unfortunately, earlier versions of smbclient/libsmbclient
255 * don't send this "standard" writeX header. I've fixed this
256 * for 3.2 but we'll use the old method with earlier versions.
257 * Windows and CIFSFS at least use this standard size. Not
258 * sure about MacOSX.
261 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
262 (2*14) + /* word count (including bcc) */ \
263 1 /* pad byte */)
265 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
266 const char lenbuf[4],
267 struct smbd_server_connection *sconn,
268 int sock,
269 char **buffer,
270 unsigned int timeout,
271 size_t *p_unread,
272 size_t *len_ret)
274 /* Size of a WRITEX call (+4 byte len). */
275 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
276 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
277 ssize_t toread;
278 NTSTATUS status;
280 memcpy(writeX_header, lenbuf, 4);
282 status = read_fd_with_timeout(
283 sock, writeX_header + 4,
284 STANDARD_WRITE_AND_X_HEADER_SIZE,
285 STANDARD_WRITE_AND_X_HEADER_SIZE,
286 timeout, NULL);
288 if (!NT_STATUS_IS_OK(status)) {
289 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
290 "error = %s.\n", sconn->client_id.addr,
291 nt_errstr(status)));
292 return status;
296 * Ok - now try and see if this is a possible
297 * valid writeX call.
300 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
302 * If the data offset is beyond what
303 * we've read, drain the extra bytes.
305 uint16_t doff = SVAL(writeX_header,smb_vwv11);
306 ssize_t newlen;
308 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
309 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
310 if (drain_socket(sock, drain) != drain) {
311 smb_panic("receive_smb_raw_talloc_partial_read:"
312 " failed to drain pending bytes");
314 } else {
315 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
318 /* Spoof down the length and null out the bcc. */
319 set_message_bcc(writeX_header, 0);
320 newlen = smb_len(writeX_header);
322 /* Copy the header we've written. */
324 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
325 writeX_header,
326 sizeof(writeX_header));
328 if (*buffer == NULL) {
329 DEBUG(0, ("Could not allocate inbuf of length %d\n",
330 (int)sizeof(writeX_header)));
331 return NT_STATUS_NO_MEMORY;
334 /* Work out the remaining bytes. */
335 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
336 *len_ret = newlen + 4;
337 return NT_STATUS_OK;
340 if (!valid_packet_size(len)) {
341 return NT_STATUS_INVALID_PARAMETER;
345 * Not a valid writeX call. Just do the standard
346 * talloc and return.
349 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
351 if (*buffer == NULL) {
352 DEBUG(0, ("Could not allocate inbuf of length %d\n",
353 (int)len+4));
354 return NT_STATUS_NO_MEMORY;
357 /* Copy in what we already read. */
358 memcpy(*buffer,
359 writeX_header,
360 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
361 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
363 if(toread > 0) {
364 status = read_packet_remainder(
365 sock,
366 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
367 timeout, toread);
369 if (!NT_STATUS_IS_OK(status)) {
370 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
371 nt_errstr(status)));
372 return status;
376 *len_ret = len + 4;
377 return NT_STATUS_OK;
380 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
381 struct smbd_server_connection *sconn,
382 int sock,
383 char **buffer, unsigned int timeout,
384 size_t *p_unread, size_t *plen)
386 char lenbuf[4];
387 size_t len;
388 int min_recv_size = lp_min_receive_file_size();
389 NTSTATUS status;
391 *p_unread = 0;
393 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
394 &len);
395 if (!NT_STATUS_IS_OK(status)) {
396 return status;
399 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
400 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
401 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
402 !srv_is_signing_active(sconn) &&
403 sconn->smb1.echo_handler.trusted_fde == NULL) {
405 return receive_smb_raw_talloc_partial_read(
406 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
407 p_unread, plen);
410 if (!valid_packet_size(len)) {
411 return NT_STATUS_INVALID_PARAMETER;
415 * The +4 here can't wrap, we've checked the length above already.
418 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
420 if (*buffer == NULL) {
421 DEBUG(0, ("Could not allocate inbuf of length %d\n",
422 (int)len+4));
423 return NT_STATUS_NO_MEMORY;
426 memcpy(*buffer, lenbuf, sizeof(lenbuf));
428 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
429 if (!NT_STATUS_IS_OK(status)) {
430 return status;
433 *plen = len + 4;
434 return NT_STATUS_OK;
437 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
438 struct smbd_server_connection *sconn,
439 int sock,
440 char **buffer, unsigned int timeout,
441 size_t *p_unread, bool *p_encrypted,
442 size_t *p_len,
443 uint32_t *seqnum,
444 bool trusted_channel)
446 size_t len = 0;
447 NTSTATUS status;
449 *p_encrypted = false;
451 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
452 p_unread, &len);
453 if (!NT_STATUS_IS_OK(status)) {
454 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
455 ("receive_smb_raw_talloc failed for client %s "
456 "read error = %s.\n",
457 sconn->client_id.addr, nt_errstr(status)));
458 return status;
461 if (is_encrypted_packet((uint8_t *)*buffer)) {
462 status = srv_decrypt_buffer(*buffer);
463 if (!NT_STATUS_IS_OK(status)) {
464 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
465 "incoming packet! Error %s\n",
466 nt_errstr(status) ));
467 return status;
469 *p_encrypted = true;
472 /* Check the incoming SMB signature. */
473 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
474 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
475 "incoming packet!\n"));
476 return NT_STATUS_INVALID_NETWORK_RESPONSE;
479 *p_len = len;
480 return NT_STATUS_OK;
484 * Initialize a struct smb_request from an inbuf
487 static bool init_smb_request(struct smb_request *req,
488 struct smbd_server_connection *sconn,
489 const uint8 *inbuf,
490 size_t unread_bytes, bool encrypted,
491 uint32_t seqnum)
493 size_t req_size = smb_len(inbuf) + 4;
494 /* Ensure we have at least smb_size bytes. */
495 if (req_size < smb_size) {
496 DEBUG(0,("init_smb_request: invalid request size %u\n",
497 (unsigned int)req_size ));
498 return false;
500 req->cmd = CVAL(inbuf, smb_com);
501 req->flags2 = SVAL(inbuf, smb_flg2);
502 req->smbpid = SVAL(inbuf, smb_pid);
503 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
504 req->seqnum = seqnum;
505 req->vuid = SVAL(inbuf, smb_uid);
506 req->tid = SVAL(inbuf, smb_tid);
507 req->wct = CVAL(inbuf, smb_wct);
508 req->vwv = (uint16_t *)(inbuf+smb_vwv);
509 req->buflen = smb_buflen(inbuf);
510 req->buf = (const uint8_t *)smb_buf(inbuf);
511 req->unread_bytes = unread_bytes;
512 req->encrypted = encrypted;
513 req->sconn = sconn;
514 req->conn = conn_find(sconn,req->tid);
515 req->chain_fsp = NULL;
516 req->chain_outbuf = NULL;
517 req->done = false;
518 req->smb2req = NULL;
519 smb_init_perfcount_data(&req->pcd);
521 /* Ensure we have at least wct words and 2 bytes of bcc. */
522 if (smb_size + req->wct*2 > req_size) {
523 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
524 (unsigned int)req->wct,
525 (unsigned int)req_size));
526 return false;
528 /* Ensure bcc is correct. */
529 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
530 DEBUG(0,("init_smb_request: invalid bcc number %u "
531 "(wct = %u, size %u)\n",
532 (unsigned int)req->buflen,
533 (unsigned int)req->wct,
534 (unsigned int)req_size));
535 return false;
538 req->outbuf = NULL;
539 return true;
542 static void process_smb(struct smbd_server_connection *conn,
543 uint8_t *inbuf, size_t nread, size_t unread_bytes,
544 uint32_t seqnum, bool encrypted,
545 struct smb_perfcount_data *deferred_pcd);
547 static void smbd_deferred_open_timer(struct event_context *ev,
548 struct timed_event *te,
549 struct timeval _tval,
550 void *private_data)
552 struct pending_message_list *msg = talloc_get_type(private_data,
553 struct pending_message_list);
554 TALLOC_CTX *mem_ctx = talloc_tos();
555 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
556 uint8_t *inbuf;
558 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
559 msg->buf.length);
560 if (inbuf == NULL) {
561 exit_server("smbd_deferred_open_timer: talloc failed\n");
562 return;
565 /* We leave this message on the queue so the open code can
566 know this is a retry. */
567 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
568 (unsigned long long)mid ));
570 /* Mark the message as processed so this is not
571 * re-processed in error. */
572 msg->processed = true;
574 process_smb(smbd_server_conn, inbuf,
575 msg->buf.length, 0,
576 msg->seqnum, msg->encrypted, &msg->pcd);
578 /* If it's still there and was processed, remove it. */
579 msg = get_deferred_open_message_smb(mid);
580 if (msg && msg->processed) {
581 remove_deferred_open_message_smb(mid);
585 /****************************************************************************
586 Function to push a message onto the tail of a linked list of smb messages ready
587 for processing.
588 ****************************************************************************/
590 static bool push_queued_message(struct smb_request *req,
591 struct timeval request_time,
592 struct timeval end_time,
593 char *private_data, size_t private_len)
595 int msg_len = smb_len(req->inbuf) + 4;
596 struct pending_message_list *msg;
598 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
600 if(msg == NULL) {
601 DEBUG(0,("push_message: malloc fail (1)\n"));
602 return False;
605 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
606 if(msg->buf.data == NULL) {
607 DEBUG(0,("push_message: malloc fail (2)\n"));
608 TALLOC_FREE(msg);
609 return False;
612 msg->request_time = request_time;
613 msg->seqnum = req->seqnum;
614 msg->encrypted = req->encrypted;
615 msg->processed = false;
616 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
618 if (private_data) {
619 msg->private_data = data_blob_talloc(msg, private_data,
620 private_len);
621 if (msg->private_data.data == NULL) {
622 DEBUG(0,("push_message: malloc fail (3)\n"));
623 TALLOC_FREE(msg);
624 return False;
628 msg->te = event_add_timed(smbd_event_context(),
629 msg,
630 end_time,
631 smbd_deferred_open_timer,
632 msg);
633 if (!msg->te) {
634 DEBUG(0,("push_message: event_add_timed failed\n"));
635 TALLOC_FREE(msg);
636 return false;
639 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
641 DEBUG(10,("push_message: pushed message length %u on "
642 "deferred_open_queue\n", (unsigned int)msg_len));
644 return True;
647 /****************************************************************************
648 Function to delete a sharing violation open message by mid.
649 ****************************************************************************/
651 void remove_deferred_open_message_smb(uint64_t mid)
653 struct pending_message_list *pml;
655 if (smbd_server_conn->using_smb2) {
656 remove_deferred_open_message_smb2(smbd_server_conn, mid);
657 return;
660 for (pml = deferred_open_queue; pml; pml = pml->next) {
661 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
662 DEBUG(10,("remove_deferred_open_message_smb: "
663 "deleting mid %llu len %u\n",
664 (unsigned long long)mid,
665 (unsigned int)pml->buf.length ));
666 DLIST_REMOVE(deferred_open_queue, pml);
667 TALLOC_FREE(pml);
668 return;
673 /****************************************************************************
674 Move a sharing violation open retry message to the front of the list and
675 schedule it for immediate processing.
676 ****************************************************************************/
678 void schedule_deferred_open_message_smb(uint64_t mid)
680 struct pending_message_list *pml;
681 int i = 0;
683 if (smbd_server_conn->using_smb2) {
684 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
685 return;
688 for (pml = deferred_open_queue; pml; pml = pml->next) {
689 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
691 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
692 "msg_mid = %llu\n",
693 i++,
694 (unsigned long long)msg_mid ));
696 if (mid == msg_mid) {
697 struct timed_event *te;
699 if (pml->processed) {
700 /* A processed message should not be
701 * rescheduled. */
702 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
703 "message mid %llu was already processed\n",
704 (unsigned long long)msg_mid ));
705 continue;
708 DEBUG(10,("schedule_deferred_open_message_smb: "
709 "scheduling mid %llu\n",
710 (unsigned long long)mid ));
712 te = event_add_timed(smbd_event_context(),
713 pml,
714 timeval_zero(),
715 smbd_deferred_open_timer,
716 pml);
717 if (!te) {
718 DEBUG(10,("schedule_deferred_open_message_smb: "
719 "event_add_timed() failed, "
720 "skipping mid %llu\n",
721 (unsigned long long)msg_mid ));
724 TALLOC_FREE(pml->te);
725 pml->te = te;
726 DLIST_PROMOTE(deferred_open_queue, pml);
727 return;
731 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
732 "find message mid %llu\n",
733 (unsigned long long)mid ));
736 /****************************************************************************
737 Return true if this mid is on the deferred queue and was not yet processed.
738 ****************************************************************************/
740 bool open_was_deferred(uint64_t mid)
742 struct pending_message_list *pml;
744 if (smbd_server_conn->using_smb2) {
745 return open_was_deferred_smb2(smbd_server_conn, mid);
748 for (pml = deferred_open_queue; pml; pml = pml->next) {
749 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
750 return True;
753 return False;
756 /****************************************************************************
757 Return the message queued by this mid.
758 ****************************************************************************/
760 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
762 struct pending_message_list *pml;
764 for (pml = deferred_open_queue; pml; pml = pml->next) {
765 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
766 return pml;
769 return NULL;
772 /****************************************************************************
773 Get the state data queued by this mid.
774 ****************************************************************************/
776 bool get_deferred_open_message_state(struct smb_request *smbreq,
777 struct timeval *p_request_time,
778 void **pp_state)
780 struct pending_message_list *pml;
782 if (smbd_server_conn->using_smb2) {
783 return get_deferred_open_message_state_smb2(smbreq->smb2req,
784 p_request_time,
785 pp_state);
788 pml = get_deferred_open_message_smb(smbreq->mid);
789 if (!pml) {
790 return false;
792 if (p_request_time) {
793 *p_request_time = pml->request_time;
795 if (pp_state) {
796 *pp_state = (void *)pml->private_data.data;
798 return true;
801 /****************************************************************************
802 Function to push a deferred open smb message onto a linked list of local smb
803 messages ready for processing.
804 ****************************************************************************/
806 bool push_deferred_open_message_smb(struct smb_request *req,
807 struct timeval request_time,
808 struct timeval timeout,
809 struct file_id id,
810 char *private_data, size_t priv_len)
812 struct timeval end_time;
814 if (req->smb2req) {
815 return push_deferred_open_message_smb2(req->smb2req,
816 request_time,
817 timeout,
819 private_data,
820 priv_len);
823 if (req->unread_bytes) {
824 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
825 "unread_bytes = %u\n",
826 (unsigned int)req->unread_bytes ));
827 smb_panic("push_deferred_open_message_smb: "
828 "logic error unread_bytes != 0" );
831 end_time = timeval_sum(&request_time, &timeout);
833 DEBUG(10,("push_deferred_open_message_smb: pushing message "
834 "len %u mid %llu timeout time [%u.%06u]\n",
835 (unsigned int) smb_len(req->inbuf)+4,
836 (unsigned long long)req->mid,
837 (unsigned int)end_time.tv_sec,
838 (unsigned int)end_time.tv_usec));
840 return push_queued_message(req, request_time, end_time,
841 private_data, priv_len);
844 struct idle_event {
845 struct timed_event *te;
846 struct timeval interval;
847 char *name;
848 bool (*handler)(const struct timeval *now, void *private_data);
849 void *private_data;
852 static void smbd_idle_event_handler(struct event_context *ctx,
853 struct timed_event *te,
854 struct timeval now,
855 void *private_data)
857 struct idle_event *event =
858 talloc_get_type_abort(private_data, struct idle_event);
860 TALLOC_FREE(event->te);
862 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
863 event->name, event->te));
865 if (!event->handler(&now, event->private_data)) {
866 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
867 event->name, event->te));
868 /* Don't repeat, delete ourselves */
869 TALLOC_FREE(event);
870 return;
873 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
874 event->name, event->te));
876 event->te = event_add_timed(ctx, event,
877 timeval_sum(&now, &event->interval),
878 smbd_idle_event_handler, event);
880 /* We can't do much but fail here. */
881 SMB_ASSERT(event->te != NULL);
884 struct idle_event *event_add_idle(struct event_context *event_ctx,
885 TALLOC_CTX *mem_ctx,
886 struct timeval interval,
887 const char *name,
888 bool (*handler)(const struct timeval *now,
889 void *private_data),
890 void *private_data)
892 struct idle_event *result;
893 struct timeval now = timeval_current();
895 result = TALLOC_P(mem_ctx, struct idle_event);
896 if (result == NULL) {
897 DEBUG(0, ("talloc failed\n"));
898 return NULL;
901 result->interval = interval;
902 result->handler = handler;
903 result->private_data = private_data;
905 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
906 DEBUG(0, ("talloc failed\n"));
907 TALLOC_FREE(result);
908 return NULL;
911 result->te = event_add_timed(event_ctx, result,
912 timeval_sum(&now, &interval),
913 smbd_idle_event_handler, result);
914 if (result->te == NULL) {
915 DEBUG(0, ("event_add_timed failed\n"));
916 TALLOC_FREE(result);
917 return NULL;
920 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
921 return result;
924 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
926 int timeout;
927 int num_pfds = 0;
928 int ret;
929 bool retry;
931 timeout = SMBD_SELECT_TIMEOUT * 1000;
934 * Are there any timed events waiting ? If so, ensure we don't
935 * select for longer than it would take to wait for them.
938 event_add_to_poll_args(smbd_event_context(), conn,
939 &conn->pfds, &num_pfds, &timeout);
941 /* Process a signal and timed events now... */
942 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
943 return NT_STATUS_RETRY;
947 int sav;
948 START_PROFILE(smbd_idle);
950 ret = sys_poll(conn->pfds, num_pfds, timeout);
951 sav = errno;
953 END_PROFILE(smbd_idle);
954 errno = sav;
957 if (ret == -1) {
958 if (errno == EINTR) {
959 return NT_STATUS_RETRY;
961 return map_nt_error_from_unix(errno);
964 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
965 num_pfds);
966 if (retry) {
967 return NT_STATUS_RETRY;
970 /* Did we timeout ? */
971 if (ret == 0) {
972 return NT_STATUS_RETRY;
975 /* should not be reached */
976 return NT_STATUS_INTERNAL_ERROR;
980 * Only allow 5 outstanding trans requests. We're allocating memory, so
981 * prevent a DoS.
984 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
986 int count = 0;
987 for (; list != NULL; list = list->next) {
989 if (list->mid == mid) {
990 return NT_STATUS_INVALID_PARAMETER;
993 count += 1;
995 if (count > 5) {
996 return NT_STATUS_INSUFFICIENT_RESOURCES;
999 return NT_STATUS_OK;
1003 These flags determine some of the permissions required to do an operation
1005 Note that I don't set NEED_WRITE on some write operations because they
1006 are used by some brain-dead clients when printing, and I don't want to
1007 force write permissions on print services.
1009 #define AS_USER (1<<0)
1010 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1011 #define TIME_INIT (1<<2)
1012 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1013 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1014 #define DO_CHDIR (1<<6)
1017 define a list of possible SMB messages and their corresponding
1018 functions. Any message that has a NULL function is unimplemented -
1019 please feel free to contribute implementations!
1021 static const struct smb_message_struct {
1022 const char *name;
1023 void (*fn)(struct smb_request *req);
1024 int flags;
1025 } smb_messages[256] = {
1027 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1028 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1029 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1030 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1031 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1032 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1033 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1034 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1035 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1036 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1037 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1038 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1039 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1040 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1041 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1042 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1043 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1044 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1045 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1046 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1047 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1048 /* 0x15 */ { NULL, NULL, 0 },
1049 /* 0x16 */ { NULL, NULL, 0 },
1050 /* 0x17 */ { NULL, NULL, 0 },
1051 /* 0x18 */ { NULL, NULL, 0 },
1052 /* 0x19 */ { NULL, NULL, 0 },
1053 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1054 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1055 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1056 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1057 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1058 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1059 /* 0x20 */ { "SMBwritec", NULL,0},
1060 /* 0x21 */ { NULL, NULL, 0 },
1061 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1062 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1063 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1064 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1065 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1066 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1067 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1068 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1069 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1070 /* 0x2b */ { "SMBecho",reply_echo,0},
1071 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1072 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1073 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1074 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1075 /* 0x30 */ { NULL, NULL, 0 },
1076 /* 0x31 */ { NULL, NULL, 0 },
1077 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1078 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1079 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1080 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1081 /* 0x36 */ { NULL, NULL, 0 },
1082 /* 0x37 */ { NULL, NULL, 0 },
1083 /* 0x38 */ { NULL, NULL, 0 },
1084 /* 0x39 */ { NULL, NULL, 0 },
1085 /* 0x3a */ { NULL, NULL, 0 },
1086 /* 0x3b */ { NULL, NULL, 0 },
1087 /* 0x3c */ { NULL, NULL, 0 },
1088 /* 0x3d */ { NULL, NULL, 0 },
1089 /* 0x3e */ { NULL, NULL, 0 },
1090 /* 0x3f */ { NULL, NULL, 0 },
1091 /* 0x40 */ { NULL, NULL, 0 },
1092 /* 0x41 */ { NULL, NULL, 0 },
1093 /* 0x42 */ { NULL, NULL, 0 },
1094 /* 0x43 */ { NULL, NULL, 0 },
1095 /* 0x44 */ { NULL, NULL, 0 },
1096 /* 0x45 */ { NULL, NULL, 0 },
1097 /* 0x46 */ { NULL, NULL, 0 },
1098 /* 0x47 */ { NULL, NULL, 0 },
1099 /* 0x48 */ { NULL, NULL, 0 },
1100 /* 0x49 */ { NULL, NULL, 0 },
1101 /* 0x4a */ { NULL, NULL, 0 },
1102 /* 0x4b */ { NULL, NULL, 0 },
1103 /* 0x4c */ { NULL, NULL, 0 },
1104 /* 0x4d */ { NULL, NULL, 0 },
1105 /* 0x4e */ { NULL, NULL, 0 },
1106 /* 0x4f */ { NULL, NULL, 0 },
1107 /* 0x50 */ { NULL, NULL, 0 },
1108 /* 0x51 */ { NULL, NULL, 0 },
1109 /* 0x52 */ { NULL, NULL, 0 },
1110 /* 0x53 */ { NULL, NULL, 0 },
1111 /* 0x54 */ { NULL, NULL, 0 },
1112 /* 0x55 */ { NULL, NULL, 0 },
1113 /* 0x56 */ { NULL, NULL, 0 },
1114 /* 0x57 */ { NULL, NULL, 0 },
1115 /* 0x58 */ { NULL, NULL, 0 },
1116 /* 0x59 */ { NULL, NULL, 0 },
1117 /* 0x5a */ { NULL, NULL, 0 },
1118 /* 0x5b */ { NULL, NULL, 0 },
1119 /* 0x5c */ { NULL, NULL, 0 },
1120 /* 0x5d */ { NULL, NULL, 0 },
1121 /* 0x5e */ { NULL, NULL, 0 },
1122 /* 0x5f */ { NULL, NULL, 0 },
1123 /* 0x60 */ { NULL, NULL, 0 },
1124 /* 0x61 */ { NULL, NULL, 0 },
1125 /* 0x62 */ { NULL, NULL, 0 },
1126 /* 0x63 */ { NULL, NULL, 0 },
1127 /* 0x64 */ { NULL, NULL, 0 },
1128 /* 0x65 */ { NULL, NULL, 0 },
1129 /* 0x66 */ { NULL, NULL, 0 },
1130 /* 0x67 */ { NULL, NULL, 0 },
1131 /* 0x68 */ { NULL, NULL, 0 },
1132 /* 0x69 */ { NULL, NULL, 0 },
1133 /* 0x6a */ { NULL, NULL, 0 },
1134 /* 0x6b */ { NULL, NULL, 0 },
1135 /* 0x6c */ { NULL, NULL, 0 },
1136 /* 0x6d */ { NULL, NULL, 0 },
1137 /* 0x6e */ { NULL, NULL, 0 },
1138 /* 0x6f */ { NULL, NULL, 0 },
1139 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1140 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1141 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1142 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1143 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1144 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1145 /* 0x76 */ { NULL, NULL, 0 },
1146 /* 0x77 */ { NULL, NULL, 0 },
1147 /* 0x78 */ { NULL, NULL, 0 },
1148 /* 0x79 */ { NULL, NULL, 0 },
1149 /* 0x7a */ { NULL, NULL, 0 },
1150 /* 0x7b */ { NULL, NULL, 0 },
1151 /* 0x7c */ { NULL, NULL, 0 },
1152 /* 0x7d */ { NULL, NULL, 0 },
1153 /* 0x7e */ { NULL, NULL, 0 },
1154 /* 0x7f */ { NULL, NULL, 0 },
1155 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1156 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1157 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1158 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1159 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1160 /* 0x85 */ { NULL, NULL, 0 },
1161 /* 0x86 */ { NULL, NULL, 0 },
1162 /* 0x87 */ { NULL, NULL, 0 },
1163 /* 0x88 */ { NULL, NULL, 0 },
1164 /* 0x89 */ { NULL, NULL, 0 },
1165 /* 0x8a */ { NULL, NULL, 0 },
1166 /* 0x8b */ { NULL, NULL, 0 },
1167 /* 0x8c */ { NULL, NULL, 0 },
1168 /* 0x8d */ { NULL, NULL, 0 },
1169 /* 0x8e */ { NULL, NULL, 0 },
1170 /* 0x8f */ { NULL, NULL, 0 },
1171 /* 0x90 */ { NULL, NULL, 0 },
1172 /* 0x91 */ { NULL, NULL, 0 },
1173 /* 0x92 */ { NULL, NULL, 0 },
1174 /* 0x93 */ { NULL, NULL, 0 },
1175 /* 0x94 */ { NULL, NULL, 0 },
1176 /* 0x95 */ { NULL, NULL, 0 },
1177 /* 0x96 */ { NULL, NULL, 0 },
1178 /* 0x97 */ { NULL, NULL, 0 },
1179 /* 0x98 */ { NULL, NULL, 0 },
1180 /* 0x99 */ { NULL, NULL, 0 },
1181 /* 0x9a */ { NULL, NULL, 0 },
1182 /* 0x9b */ { NULL, NULL, 0 },
1183 /* 0x9c */ { NULL, NULL, 0 },
1184 /* 0x9d */ { NULL, NULL, 0 },
1185 /* 0x9e */ { NULL, NULL, 0 },
1186 /* 0x9f */ { NULL, NULL, 0 },
1187 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1188 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1189 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1190 /* 0xa3 */ { NULL, NULL, 0 },
1191 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1192 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1193 /* 0xa6 */ { NULL, NULL, 0 },
1194 /* 0xa7 */ { NULL, NULL, 0 },
1195 /* 0xa8 */ { NULL, NULL, 0 },
1196 /* 0xa9 */ { NULL, NULL, 0 },
1197 /* 0xaa */ { NULL, NULL, 0 },
1198 /* 0xab */ { NULL, NULL, 0 },
1199 /* 0xac */ { NULL, NULL, 0 },
1200 /* 0xad */ { NULL, NULL, 0 },
1201 /* 0xae */ { NULL, NULL, 0 },
1202 /* 0xaf */ { NULL, NULL, 0 },
1203 /* 0xb0 */ { NULL, NULL, 0 },
1204 /* 0xb1 */ { NULL, NULL, 0 },
1205 /* 0xb2 */ { NULL, NULL, 0 },
1206 /* 0xb3 */ { NULL, NULL, 0 },
1207 /* 0xb4 */ { NULL, NULL, 0 },
1208 /* 0xb5 */ { NULL, NULL, 0 },
1209 /* 0xb6 */ { NULL, NULL, 0 },
1210 /* 0xb7 */ { NULL, NULL, 0 },
1211 /* 0xb8 */ { NULL, NULL, 0 },
1212 /* 0xb9 */ { NULL, NULL, 0 },
1213 /* 0xba */ { NULL, NULL, 0 },
1214 /* 0xbb */ { NULL, NULL, 0 },
1215 /* 0xbc */ { NULL, NULL, 0 },
1216 /* 0xbd */ { NULL, NULL, 0 },
1217 /* 0xbe */ { NULL, NULL, 0 },
1218 /* 0xbf */ { NULL, NULL, 0 },
1219 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1220 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1221 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1222 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1223 /* 0xc4 */ { NULL, NULL, 0 },
1224 /* 0xc5 */ { NULL, NULL, 0 },
1225 /* 0xc6 */ { NULL, NULL, 0 },
1226 /* 0xc7 */ { NULL, NULL, 0 },
1227 /* 0xc8 */ { NULL, NULL, 0 },
1228 /* 0xc9 */ { NULL, NULL, 0 },
1229 /* 0xca */ { NULL, NULL, 0 },
1230 /* 0xcb */ { NULL, NULL, 0 },
1231 /* 0xcc */ { NULL, NULL, 0 },
1232 /* 0xcd */ { NULL, NULL, 0 },
1233 /* 0xce */ { NULL, NULL, 0 },
1234 /* 0xcf */ { NULL, NULL, 0 },
1235 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1236 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1237 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1238 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1239 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1240 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1241 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1242 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1243 /* 0xd8 */ { NULL, NULL, 0 },
1244 /* 0xd9 */ { NULL, NULL, 0 },
1245 /* 0xda */ { NULL, NULL, 0 },
1246 /* 0xdb */ { NULL, NULL, 0 },
1247 /* 0xdc */ { NULL, NULL, 0 },
1248 /* 0xdd */ { NULL, NULL, 0 },
1249 /* 0xde */ { NULL, NULL, 0 },
1250 /* 0xdf */ { NULL, NULL, 0 },
1251 /* 0xe0 */ { NULL, NULL, 0 },
1252 /* 0xe1 */ { NULL, NULL, 0 },
1253 /* 0xe2 */ { NULL, NULL, 0 },
1254 /* 0xe3 */ { NULL, NULL, 0 },
1255 /* 0xe4 */ { NULL, NULL, 0 },
1256 /* 0xe5 */ { NULL, NULL, 0 },
1257 /* 0xe6 */ { NULL, NULL, 0 },
1258 /* 0xe7 */ { NULL, NULL, 0 },
1259 /* 0xe8 */ { NULL, NULL, 0 },
1260 /* 0xe9 */ { NULL, NULL, 0 },
1261 /* 0xea */ { NULL, NULL, 0 },
1262 /* 0xeb */ { NULL, NULL, 0 },
1263 /* 0xec */ { NULL, NULL, 0 },
1264 /* 0xed */ { NULL, NULL, 0 },
1265 /* 0xee */ { NULL, NULL, 0 },
1266 /* 0xef */ { NULL, NULL, 0 },
1267 /* 0xf0 */ { NULL, NULL, 0 },
1268 /* 0xf1 */ { NULL, NULL, 0 },
1269 /* 0xf2 */ { NULL, NULL, 0 },
1270 /* 0xf3 */ { NULL, NULL, 0 },
1271 /* 0xf4 */ { NULL, NULL, 0 },
1272 /* 0xf5 */ { NULL, NULL, 0 },
1273 /* 0xf6 */ { NULL, NULL, 0 },
1274 /* 0xf7 */ { NULL, NULL, 0 },
1275 /* 0xf8 */ { NULL, NULL, 0 },
1276 /* 0xf9 */ { NULL, NULL, 0 },
1277 /* 0xfa */ { NULL, NULL, 0 },
1278 /* 0xfb */ { NULL, NULL, 0 },
1279 /* 0xfc */ { NULL, NULL, 0 },
1280 /* 0xfd */ { NULL, NULL, 0 },
1281 /* 0xfe */ { NULL, NULL, 0 },
1282 /* 0xff */ { NULL, NULL, 0 }
1286 /*******************************************************************
1287 allocate and initialize a reply packet
1288 ********************************************************************/
1290 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1291 const char *inbuf, char **outbuf, uint8_t num_words,
1292 uint32_t num_bytes)
1295 * Protect against integer wrap
1297 if ((num_bytes > 0xffffff)
1298 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1299 char *msg;
1300 if (asprintf(&msg, "num_bytes too large: %u",
1301 (unsigned)num_bytes) == -1) {
1302 msg = CONST_DISCARD(char *, "num_bytes too large");
1304 smb_panic(msg);
1307 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1308 smb_size + num_words*2 + num_bytes);
1309 if (*outbuf == NULL) {
1310 return false;
1313 construct_reply_common(req, inbuf, *outbuf);
1314 srv_set_message(*outbuf, num_words, num_bytes, false);
1316 * Zero out the word area, the caller has to take care of the bcc area
1317 * himself
1319 if (num_words != 0) {
1320 memset(*outbuf + smb_vwv0, 0, num_words*2);
1323 return true;
1326 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1328 char *outbuf;
1329 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1330 num_bytes)) {
1331 smb_panic("could not allocate output buffer\n");
1333 req->outbuf = (uint8_t *)outbuf;
1337 /*******************************************************************
1338 Dump a packet to a file.
1339 ********************************************************************/
1341 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1343 int fd, i;
1344 char *fname = NULL;
1345 if (DEBUGLEVEL < 50) {
1346 return;
1349 if (len < 4) len = smb_len(data)+4;
1350 for (i=1;i<100;i++) {
1351 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1352 type ? "req" : "resp") == -1) {
1353 return;
1355 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1356 if (fd != -1 || errno != EEXIST) break;
1358 if (fd != -1) {
1359 ssize_t ret = write(fd, data, len);
1360 if (ret != len)
1361 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1362 close(fd);
1363 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1365 SAFE_FREE(fname);
1368 /****************************************************************************
1369 Prepare everything for calling the actual request function, and potentially
1370 call the request function via the "new" interface.
1372 Return False if the "legacy" function needs to be called, everything is
1373 prepared.
1375 Return True if we're done.
1377 I know this API sucks, but it is the one with the least code change I could
1378 find.
1379 ****************************************************************************/
1381 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1383 int flags;
1384 uint16 session_tag;
1385 connection_struct *conn = NULL;
1386 struct smbd_server_connection *sconn = req->sconn;
1388 errno = 0;
1390 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1391 * so subtract 4 from it. */
1392 if ((size < (smb_size - 4)) ||
1393 !valid_smb_header(req->inbuf)) {
1394 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1395 smb_len(req->inbuf)));
1396 exit_server_cleanly("Non-SMB packet");
1399 if (smb_messages[type].fn == NULL) {
1400 DEBUG(0,("Unknown message type %d!\n",type));
1401 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1402 reply_unknown_new(req, type);
1403 return NULL;
1406 flags = smb_messages[type].flags;
1408 /* In share mode security we must ignore the vuid. */
1409 session_tag = (lp_security() == SEC_SHARE)
1410 ? UID_FIELD_INVALID : req->vuid;
1411 conn = req->conn;
1413 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1414 (int)sys_getpid(), (unsigned long)conn));
1416 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1418 /* Ensure this value is replaced in the incoming packet. */
1419 SSVAL(req->inbuf,smb_uid,session_tag);
1422 * Ensure the correct username is in current_user_info. This is a
1423 * really ugly bugfix for problems with multiple session_setup_and_X's
1424 * being done and allowing %U and %G substitutions to work correctly.
1425 * There is a reason this code is done here, don't move it unless you
1426 * know what you're doing... :-).
1427 * JRA.
1430 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1431 user_struct *vuser = NULL;
1433 sconn->smb1.sessions.last_session_tag = session_tag;
1434 if(session_tag != UID_FIELD_INVALID) {
1435 vuser = get_valid_user_struct(sconn, session_tag);
1436 if (vuser) {
1437 set_current_user_info(
1438 vuser->session_info->sanitized_username,
1439 vuser->session_info->unix_name,
1440 vuser->session_info->info3->base.domain.string);
1445 /* Does this call need to be run as the connected user? */
1446 if (flags & AS_USER) {
1448 /* Does this call need a valid tree connection? */
1449 if (!conn) {
1451 * Amazingly, the error code depends on the command
1452 * (from Samba4).
1454 if (type == SMBntcreateX) {
1455 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1456 } else {
1457 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1459 return NULL;
1462 if (!change_to_user(conn,session_tag)) {
1463 DEBUG(0, ("Error: Could not change to user. Removing "
1464 "deferred open, mid=%llu.\n",
1465 (unsigned long long)req->mid));
1466 reply_force_doserror(req, ERRSRV, ERRbaduid);
1467 return conn;
1470 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1472 /* Does it need write permission? */
1473 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1474 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1475 return conn;
1478 /* IPC services are limited */
1479 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1480 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1481 return conn;
1483 } else {
1484 /* This call needs to be run as root */
1485 change_to_root_user();
1488 /* load service specific parameters */
1489 if (conn) {
1490 if (req->encrypted) {
1491 conn->encrypted_tid = true;
1492 /* encrypted required from now on. */
1493 conn->encrypt_level = Required;
1494 } else if (ENCRYPTION_REQUIRED(conn)) {
1495 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1496 exit_server_cleanly("encryption required "
1497 "on connection");
1498 return conn;
1502 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1503 (flags & (AS_USER|DO_CHDIR)
1504 ?True:False))) {
1505 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1506 return conn;
1508 conn->num_smb_operations++;
1511 /* does this protocol need to be run as guest? */
1512 if ((flags & AS_GUEST)
1513 && (!change_to_guest() ||
1514 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1515 sconn->client_id.name,
1516 sconn->client_id.addr))) {
1517 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1518 return conn;
1521 smb_messages[type].fn(req);
1522 return req->conn;
1525 /****************************************************************************
1526 Construct a reply to the incoming packet.
1527 ****************************************************************************/
1529 static void construct_reply(struct smbd_server_connection *sconn,
1530 char *inbuf, int size, size_t unread_bytes,
1531 uint32_t seqnum, bool encrypted,
1532 struct smb_perfcount_data *deferred_pcd)
1534 connection_struct *conn;
1535 struct smb_request *req;
1537 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1538 smb_panic("could not allocate smb_request");
1541 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1542 encrypted, seqnum)) {
1543 exit_server_cleanly("Invalid SMB request");
1546 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1548 /* we popped this message off the queue - keep original perf data */
1549 if (deferred_pcd)
1550 req->pcd = *deferred_pcd;
1551 else {
1552 SMB_PERFCOUNT_START(&req->pcd);
1553 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1554 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1557 conn = switch_message(req->cmd, req, size);
1559 if (req->unread_bytes) {
1560 /* writeX failed. drain socket. */
1561 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1562 req->unread_bytes) {
1563 smb_panic("failed to drain pending bytes");
1565 req->unread_bytes = 0;
1568 if (req->done) {
1569 TALLOC_FREE(req);
1570 return;
1573 if (req->outbuf == NULL) {
1574 return;
1577 if (CVAL(req->outbuf,0) == 0) {
1578 show_msg((char *)req->outbuf);
1581 if (!srv_send_smb(req->sconn,
1582 (char *)req->outbuf,
1583 true, req->seqnum+1,
1584 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1585 &req->pcd)) {
1586 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1589 TALLOC_FREE(req);
1591 return;
1594 /****************************************************************************
1595 Process an smb from the client
1596 ****************************************************************************/
1597 static void process_smb(struct smbd_server_connection *sconn,
1598 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1599 uint32_t seqnum, bool encrypted,
1600 struct smb_perfcount_data *deferred_pcd)
1602 int msg_type = CVAL(inbuf,0);
1604 DO_PROFILE_INC(smb_count);
1606 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1607 smb_len(inbuf) ) );
1608 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1609 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1611 if (msg_type != 0) {
1613 * NetBIOS session request, keepalive, etc.
1615 reply_special(sconn, (char *)inbuf, nread);
1616 goto done;
1619 if (sconn->using_smb2) {
1620 /* At this point we're not really using smb2,
1621 * we make the decision here.. */
1622 if (smbd_is_smb2_header(inbuf, nread)) {
1623 smbd_smb2_first_negprot(sconn, inbuf, nread);
1624 return;
1625 } else if (nread >= smb_size && valid_smb_header(inbuf)
1626 && CVAL(inbuf, smb_com) != 0x72) {
1627 /* This is a non-negprot SMB1 packet.
1628 Disable SMB2 from now on. */
1629 sconn->using_smb2 = false;
1633 show_msg((char *)inbuf);
1635 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1636 encrypted, deferred_pcd);
1637 sconn->trans_num++;
1639 done:
1640 sconn->num_requests++;
1642 /* The timeout_processing function isn't run nearly
1643 often enough to implement 'max log size' without
1644 overrunning the size of the file by many megabytes.
1645 This is especially true if we are running at debug
1646 level 10. Checking every 50 SMBs is a nice
1647 tradeoff of performance vs log file size overrun. */
1649 if ((sconn->num_requests % 50) == 0 &&
1650 need_to_check_log_size()) {
1651 change_to_root_user();
1652 check_log_size();
1656 /****************************************************************************
1657 Return a string containing the function name of a SMB command.
1658 ****************************************************************************/
1660 const char *smb_fn_name(int type)
1662 const char *unknown_name = "SMBunknown";
1664 if (smb_messages[type].name == NULL)
1665 return(unknown_name);
1667 return(smb_messages[type].name);
1670 /****************************************************************************
1671 Helper functions for contruct_reply.
1672 ****************************************************************************/
1674 void add_to_common_flags2(uint32 v)
1676 common_flags2 |= v;
1679 void remove_from_common_flags2(uint32 v)
1681 common_flags2 &= ~v;
1684 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1685 char *outbuf)
1687 srv_set_message(outbuf,0,0,false);
1689 SCVAL(outbuf, smb_com, req->cmd);
1690 SIVAL(outbuf,smb_rcls,0);
1691 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1692 SSVAL(outbuf,smb_flg2,
1693 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1694 common_flags2);
1695 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1697 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1698 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1699 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1700 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1703 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1705 construct_reply_common(req, (char *)req->inbuf, outbuf);
1709 * How many bytes have we already accumulated up to the current wct field
1710 * offset?
1713 size_t req_wct_ofs(struct smb_request *req)
1715 size_t buf_size;
1717 if (req->chain_outbuf == NULL) {
1718 return smb_wct - 4;
1720 buf_size = talloc_get_size(req->chain_outbuf);
1721 if ((buf_size % 4) != 0) {
1722 buf_size += (4 - (buf_size % 4));
1724 return buf_size - 4;
1728 * Hack around reply_nterror & friends not being aware of chained requests,
1729 * generating illegal (i.e. wct==0) chain replies.
1732 static void fixup_chain_error_packet(struct smb_request *req)
1734 uint8_t *outbuf = req->outbuf;
1735 req->outbuf = NULL;
1736 reply_outbuf(req, 2, 0);
1737 memcpy(req->outbuf, outbuf, smb_wct);
1738 TALLOC_FREE(outbuf);
1739 SCVAL(req->outbuf, smb_vwv0, 0xff);
1743 * @brief Find the smb_cmd offset of the last command pushed
1744 * @param[in] buf The buffer we're building up
1745 * @retval Where can we put our next andx cmd?
1747 * While chaining requests, the "next" request we're looking at needs to put
1748 * its SMB_Command before the data the previous request already built up added
1749 * to the chain. Find the offset to the place where we have to put our cmd.
1752 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1754 uint8_t cmd;
1755 size_t ofs;
1757 cmd = CVAL(buf, smb_com);
1759 SMB_ASSERT(is_andx_req(cmd));
1761 ofs = smb_vwv0;
1763 while (CVAL(buf, ofs) != 0xff) {
1765 if (!is_andx_req(CVAL(buf, ofs))) {
1766 return false;
1770 * ofs is from start of smb header, so add the 4 length
1771 * bytes. The next cmd is right after the wct field.
1773 ofs = SVAL(buf, ofs+2) + 4 + 1;
1775 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1778 *pofs = ofs;
1779 return true;
1783 * @brief Do the smb chaining at a buffer level
1784 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1785 * @param[in] smb_command The command that we want to issue
1786 * @param[in] wct How many words?
1787 * @param[in] vwv The words, already in network order
1788 * @param[in] bytes_alignment How shall we align "bytes"?
1789 * @param[in] num_bytes How many bytes?
1790 * @param[in] bytes The data the request ships
1792 * smb_splice_chain() adds the vwv and bytes to the request already present in
1793 * *poutbuf.
1796 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1797 uint8_t wct, const uint16_t *vwv,
1798 size_t bytes_alignment,
1799 uint32_t num_bytes, const uint8_t *bytes)
1801 uint8_t *outbuf;
1802 size_t old_size, new_size;
1803 size_t ofs;
1804 size_t chain_padding = 0;
1805 size_t bytes_padding = 0;
1806 bool first_request;
1808 old_size = talloc_get_size(*poutbuf);
1811 * old_size == smb_wct means we're pushing the first request in for
1812 * libsmb/
1815 first_request = (old_size == smb_wct);
1817 if (!first_request && ((old_size % 4) != 0)) {
1819 * Align the wct field of subsequent requests to a 4-byte
1820 * boundary
1822 chain_padding = 4 - (old_size % 4);
1826 * After the old request comes the new wct field (1 byte), the vwv's
1827 * and the num_bytes field. After at we might need to align the bytes
1828 * given to us to "bytes_alignment", increasing the num_bytes value.
1831 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1833 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1834 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1837 new_size += bytes_padding + num_bytes;
1839 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1840 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1841 (unsigned)new_size));
1842 return false;
1845 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1846 if (outbuf == NULL) {
1847 DEBUG(0, ("talloc failed\n"));
1848 return false;
1850 *poutbuf = outbuf;
1852 if (first_request) {
1853 SCVAL(outbuf, smb_com, smb_command);
1854 } else {
1855 size_t andx_cmd_ofs;
1857 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1858 DEBUG(1, ("invalid command chain\n"));
1859 *poutbuf = TALLOC_REALLOC_ARRAY(
1860 NULL, *poutbuf, uint8_t, old_size);
1861 return false;
1864 if (chain_padding != 0) {
1865 memset(outbuf + old_size, 0, chain_padding);
1866 old_size += chain_padding;
1869 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1870 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1873 ofs = old_size;
1876 * Push the chained request:
1878 * wct field
1881 SCVAL(outbuf, ofs, wct);
1882 ofs += 1;
1885 * vwv array
1888 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1889 ofs += sizeof(uint16_t) * wct;
1892 * bcc (byte count)
1895 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1896 ofs += sizeof(uint16_t);
1899 * padding
1902 if (bytes_padding != 0) {
1903 memset(outbuf + ofs, 0, bytes_padding);
1904 ofs += bytes_padding;
1908 * The bytes field
1911 memcpy(outbuf + ofs, bytes, num_bytes);
1913 return true;
1916 /****************************************************************************
1917 Construct a chained reply and add it to the already made reply
1918 ****************************************************************************/
1920 void chain_reply(struct smb_request *req)
1922 size_t smblen = smb_len(req->inbuf);
1923 size_t already_used, length_needed;
1924 uint8_t chain_cmd;
1925 uint32_t chain_offset; /* uint32_t to avoid overflow */
1927 uint8_t wct;
1928 uint16_t *vwv;
1929 uint16_t buflen;
1930 uint8_t *buf;
1932 if (IVAL(req->outbuf, smb_rcls) != 0) {
1933 fixup_chain_error_packet(req);
1937 * Any of the AndX requests and replies have at least a wct of
1938 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1939 * beginning of the SMB header to the next wct field.
1941 * None of the AndX requests put anything valuable in vwv[0] and [1],
1942 * so we can overwrite it here to form the chain.
1945 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1946 if (req->chain_outbuf == NULL) {
1947 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1948 req, req->outbuf, uint8_t,
1949 smb_len(req->outbuf) + 4);
1950 if (req->chain_outbuf == NULL) {
1951 smb_panic("talloc failed");
1954 req->outbuf = NULL;
1955 goto error;
1959 * Here we assume that this is the end of the chain. For that we need
1960 * to set "next command" to 0xff and the offset to 0. If we later find
1961 * more commands in the chain, this will be overwritten again.
1964 SCVAL(req->outbuf, smb_vwv0, 0xff);
1965 SCVAL(req->outbuf, smb_vwv0+1, 0);
1966 SSVAL(req->outbuf, smb_vwv1, 0);
1968 if (req->chain_outbuf == NULL) {
1970 * In req->chain_outbuf we collect all the replies. Start the
1971 * chain by copying in the first reply.
1973 * We do the realloc because later on we depend on
1974 * talloc_get_size to determine the length of
1975 * chain_outbuf. The reply_xxx routines might have
1976 * over-allocated (reply_pipe_read_and_X used to be such an
1977 * example).
1979 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1980 req, req->outbuf, uint8_t,
1981 smb_len_large(req->outbuf) + 4);
1982 if (req->chain_outbuf == NULL) {
1983 smb_panic("talloc failed");
1985 req->outbuf = NULL;
1986 } else {
1988 * Update smb headers where subsequent chained commands
1989 * may have updated them.
1991 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1992 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1994 if (!smb_splice_chain(&req->chain_outbuf,
1995 CVAL(req->outbuf, smb_com),
1996 CVAL(req->outbuf, smb_wct),
1997 (uint16_t *)(req->outbuf + smb_vwv),
1998 0, smb_buflen(req->outbuf),
1999 (uint8_t *)smb_buf(req->outbuf))) {
2000 goto error;
2002 TALLOC_FREE(req->outbuf);
2006 * We use the old request's vwv field to grab the next chained command
2007 * and offset into the chained fields.
2010 chain_cmd = CVAL(req->vwv+0, 0);
2011 chain_offset = SVAL(req->vwv+1, 0);
2013 if (chain_cmd == 0xff) {
2015 * End of chain, no more requests from the client. So ship the
2016 * replies.
2018 smb_setlen((char *)(req->chain_outbuf),
2019 talloc_get_size(req->chain_outbuf) - 4);
2021 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2022 true, req->seqnum+1,
2023 IS_CONN_ENCRYPTED(req->conn)
2024 ||req->encrypted,
2025 &req->pcd)) {
2026 exit_server_cleanly("chain_reply: srv_send_smb "
2027 "failed.");
2029 TALLOC_FREE(req->chain_outbuf);
2030 req->done = true;
2031 return;
2034 /* add a new perfcounter for this element of chain */
2035 SMB_PERFCOUNT_ADD(&req->pcd);
2036 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2037 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2040 * Check if the client tries to fool us. The chain offset
2041 * needs to point beyond the current request in the chain, it
2042 * needs to strictly grow. Otherwise we might be tricked into
2043 * an endless loop always processing the same request over and
2044 * over again. We used to assume that vwv and the byte buffer
2045 * array in a chain are always attached, but OS/2 the
2046 * Write&X/Read&X chain puts the Read&X vwv array right behind
2047 * the Write&X vwv chain. The Write&X bcc array is put behind
2048 * the Read&X vwv array. So now we check whether the chain
2049 * offset points strictly behind the previous vwv
2050 * array. req->buf points right after the vwv array of the
2051 * previous request. See
2052 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2053 * information.
2056 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2057 if (chain_offset <= already_used) {
2058 goto error;
2062 * Next check: Make sure the chain offset does not point beyond the
2063 * overall smb request length.
2066 length_needed = chain_offset+1; /* wct */
2067 if (length_needed > smblen) {
2068 goto error;
2072 * Now comes the pointer magic. Goal here is to set up req->vwv and
2073 * req->buf correctly again to be able to call the subsequent
2074 * switch_message(). The chain offset (the former vwv[1]) points at
2075 * the new wct field.
2078 wct = CVAL(smb_base(req->inbuf), chain_offset);
2081 * Next consistency check: Make the new vwv array fits in the overall
2082 * smb request.
2085 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2086 if (length_needed > smblen) {
2087 goto error;
2089 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2092 * Now grab the new byte buffer....
2095 buflen = SVAL(vwv+wct, 0);
2098 * .. and check that it fits.
2101 length_needed += buflen;
2102 if (length_needed > smblen) {
2103 goto error;
2105 buf = (uint8_t *)(vwv+wct+1);
2107 req->cmd = chain_cmd;
2108 req->wct = wct;
2109 req->vwv = vwv;
2110 req->buflen = buflen;
2111 req->buf = buf;
2113 switch_message(chain_cmd, req, smblen);
2115 if (req->outbuf == NULL) {
2117 * This happens if the chained command has suspended itself or
2118 * if it has called srv_send_smb() itself.
2120 return;
2124 * We end up here if the chained command was not itself chained or
2125 * suspended, but for example a close() command. We now need to splice
2126 * the chained commands' outbuf into the already built up chain_outbuf
2127 * and ship the result.
2129 goto done;
2131 error:
2133 * We end up here if there's any error in the chain syntax. Report a
2134 * DOS error, just like Windows does.
2136 reply_force_doserror(req, ERRSRV, ERRerror);
2137 fixup_chain_error_packet(req);
2139 done:
2141 * This scary statement intends to set the
2142 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2143 * to the value req->outbuf carries
2145 SSVAL(req->chain_outbuf, smb_flg2,
2146 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2147 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2150 * Transfer the error codes from the subrequest to the main one
2152 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2153 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2155 if (!smb_splice_chain(&req->chain_outbuf,
2156 CVAL(req->outbuf, smb_com),
2157 CVAL(req->outbuf, smb_wct),
2158 (uint16_t *)(req->outbuf + smb_vwv),
2159 0, smb_buflen(req->outbuf),
2160 (uint8_t *)smb_buf(req->outbuf))) {
2161 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2163 TALLOC_FREE(req->outbuf);
2165 smb_setlen((char *)(req->chain_outbuf),
2166 talloc_get_size(req->chain_outbuf) - 4);
2168 show_msg((char *)(req->chain_outbuf));
2170 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2171 true, req->seqnum+1,
2172 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2173 &req->pcd)) {
2174 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2176 TALLOC_FREE(req->chain_outbuf);
2177 req->done = true;
2180 /****************************************************************************
2181 Check if services need reloading.
2182 ****************************************************************************/
2184 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2187 if (last_smb_conf_reload_time == 0) {
2188 last_smb_conf_reload_time = t;
2191 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2192 reload_services(sconn->msg_ctx, sconn->sock, True);
2193 last_smb_conf_reload_time = t;
2197 static bool fd_is_readable(int fd)
2199 int ret, revents;
2201 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2203 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2207 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2209 /* TODO: make write nonblocking */
2212 static void smbd_server_connection_read_handler(
2213 struct smbd_server_connection *conn, int fd)
2215 uint8_t *inbuf = NULL;
2216 size_t inbuf_len = 0;
2217 size_t unread_bytes = 0;
2218 bool encrypted = false;
2219 TALLOC_CTX *mem_ctx = talloc_tos();
2220 NTSTATUS status;
2221 uint32_t seqnum;
2223 bool from_client = (conn->sock == fd);
2225 if (from_client) {
2226 smbd_lock_socket(conn);
2228 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2229 DEBUG(10,("the echo listener was faster\n"));
2230 smbd_unlock_socket(conn);
2231 return;
2234 /* TODO: make this completely nonblocking */
2235 status = receive_smb_talloc(mem_ctx, conn, fd,
2236 (char **)(void *)&inbuf,
2237 0, /* timeout */
2238 &unread_bytes,
2239 &encrypted,
2240 &inbuf_len, &seqnum,
2241 false /* trusted channel */);
2242 smbd_unlock_socket(conn);
2243 } else {
2244 /* TODO: make this completely nonblocking */
2245 status = receive_smb_talloc(mem_ctx, conn, fd,
2246 (char **)(void *)&inbuf,
2247 0, /* timeout */
2248 &unread_bytes,
2249 &encrypted,
2250 &inbuf_len, &seqnum,
2251 true /* trusted channel */);
2254 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2255 goto process;
2257 if (NT_STATUS_IS_ERR(status)) {
2258 exit_server_cleanly("failed to receive smb request");
2260 if (!NT_STATUS_IS_OK(status)) {
2261 return;
2264 process:
2265 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2266 seqnum, encrypted, NULL);
2269 static void smbd_server_connection_handler(struct event_context *ev,
2270 struct fd_event *fde,
2271 uint16_t flags,
2272 void *private_data)
2274 struct smbd_server_connection *conn = talloc_get_type(private_data,
2275 struct smbd_server_connection);
2277 if (flags & EVENT_FD_WRITE) {
2278 smbd_server_connection_write_handler(conn);
2279 return;
2281 if (flags & EVENT_FD_READ) {
2282 smbd_server_connection_read_handler(conn, conn->sock);
2283 return;
2287 static void smbd_server_echo_handler(struct event_context *ev,
2288 struct fd_event *fde,
2289 uint16_t flags,
2290 void *private_data)
2292 struct smbd_server_connection *conn = talloc_get_type(private_data,
2293 struct smbd_server_connection);
2295 if (flags & EVENT_FD_WRITE) {
2296 smbd_server_connection_write_handler(conn);
2297 return;
2299 if (flags & EVENT_FD_READ) {
2300 smbd_server_connection_read_handler(
2301 conn, conn->smb1.echo_handler.trusted_fd);
2302 return;
2306 /****************************************************************************
2307 received when we should release a specific IP
2308 ****************************************************************************/
2309 static void release_ip(const char *ip, void *priv)
2311 const char *addr = (const char *)priv;
2312 const char *p = addr;
2314 if (strncmp("::ffff:", addr, 7) == 0) {
2315 p = addr + 7;
2318 DEBUG(10, ("Got release IP message for %s, "
2319 "our address is %s\n", ip, p));
2321 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2322 /* we can't afford to do a clean exit - that involves
2323 database writes, which would potentially mean we
2324 are still running after the failover has finished -
2325 we have to get rid of this process ID straight
2326 away */
2327 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2328 ip));
2329 /* note we must exit with non-zero status so the unclean handler gets
2330 called in the parent, so that the brl database is tickled */
2331 _exit(1);
2335 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2336 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2338 struct smbd_server_connection *sconn = talloc_get_type_abort(
2339 private_data, struct smbd_server_connection);
2341 release_ip((char *)data->data, sconn->client_id.addr);
2344 #ifdef CLUSTER_SUPPORT
2345 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2346 struct sockaddr_storage *client)
2348 socklen_t length;
2349 length = sizeof(*server);
2350 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2351 return -1;
2353 length = sizeof(*client);
2354 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2355 return -1;
2357 return 0;
2359 #endif
2362 * Send keepalive packets to our client
2364 static bool keepalive_fn(const struct timeval *now, void *private_data)
2366 struct smbd_server_connection *sconn = smbd_server_conn;
2367 bool ret;
2369 if (sconn->using_smb2) {
2370 /* Don't do keepalives on an SMB2 connection. */
2371 return false;
2374 smbd_lock_socket(smbd_server_conn);
2375 ret = send_keepalive(sconn->sock);
2376 smbd_unlock_socket(smbd_server_conn);
2378 if (!ret) {
2379 char addr[INET6_ADDRSTRLEN];
2381 * Try and give an error message saying what
2382 * client failed.
2384 DEBUG(0, ("send_keepalive failed for client %s. "
2385 "Error %s - exiting\n",
2386 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2387 strerror(errno)));
2388 return False;
2390 return True;
2394 * Do the recurring check if we're idle
2396 static bool deadtime_fn(const struct timeval *now, void *private_data)
2398 struct smbd_server_connection *sconn =
2399 (struct smbd_server_connection *)private_data;
2401 if ((conn_num_open(sconn) == 0)
2402 || (conn_idle_all(sconn, now->tv_sec))) {
2403 DEBUG( 2, ( "Closing idle connection\n" ) );
2404 messaging_send(sconn->msg_ctx,
2405 messaging_server_id(sconn->msg_ctx),
2406 MSG_SHUTDOWN, &data_blob_null);
2407 return False;
2410 return True;
2414 * Do the recurring log file and smb.conf reload checks.
2417 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2419 struct smbd_server_connection *sconn = talloc_get_type_abort(
2420 private_data, struct smbd_server_connection);
2422 DEBUG(5, ("housekeeping\n"));
2424 change_to_root_user();
2426 /* update printer queue caches if necessary */
2427 update_monitored_printq_cache(sconn->msg_ctx);
2429 /* check if we need to reload services */
2430 check_reload(sconn, time_mono(NULL));
2432 /* Change machine password if neccessary. */
2433 attempt_machine_password_change();
2436 * Force a log file check.
2438 force_check_log_size();
2439 check_log_size();
2440 return true;
2443 static int create_unlink_tmp(const char *dir)
2445 char *fname;
2446 int fd;
2448 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2449 if (fname == NULL) {
2450 errno = ENOMEM;
2451 return -1;
2453 fd = mkstemp(fname);
2454 if (fd == -1) {
2455 TALLOC_FREE(fname);
2456 return -1;
2458 if (unlink(fname) == -1) {
2459 int sys_errno = errno;
2460 close(fd);
2461 TALLOC_FREE(fname);
2462 errno = sys_errno;
2463 return -1;
2465 TALLOC_FREE(fname);
2466 return fd;
2469 struct smbd_echo_state {
2470 struct tevent_context *ev;
2471 struct iovec *pending;
2472 struct smbd_server_connection *sconn;
2473 int parent_pipe;
2475 struct tevent_fd *parent_fde;
2477 struct tevent_fd *read_fde;
2478 struct tevent_req *write_req;
2481 static void smbd_echo_writer_done(struct tevent_req *req);
2483 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2485 int num_pending;
2487 if (state->write_req != NULL) {
2488 return;
2491 num_pending = talloc_array_length(state->pending);
2492 if (num_pending == 0) {
2493 return;
2496 state->write_req = writev_send(state, state->ev, NULL,
2497 state->parent_pipe, false,
2498 state->pending, num_pending);
2499 if (state->write_req == NULL) {
2500 DEBUG(1, ("writev_send failed\n"));
2501 exit(1);
2504 talloc_steal(state->write_req, state->pending);
2505 state->pending = NULL;
2507 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2508 state);
2511 static void smbd_echo_writer_done(struct tevent_req *req)
2513 struct smbd_echo_state *state = tevent_req_callback_data(
2514 req, struct smbd_echo_state);
2515 ssize_t written;
2516 int err;
2518 written = writev_recv(req, &err);
2519 TALLOC_FREE(req);
2520 state->write_req = NULL;
2521 if (written == -1) {
2522 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2523 exit(1);
2525 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2526 smbd_echo_activate_writer(state);
2529 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2530 uint32_t seqnum)
2532 struct smb_request req;
2533 uint16_t num_replies;
2534 size_t out_len;
2535 char *outbuf;
2536 bool ok;
2538 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2539 DEBUG(10, ("Got netbios keepalive\n"));
2541 * Just swallow it
2543 return true;
2546 if (inbuf_len < smb_size) {
2547 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2548 return false;
2550 if (!valid_smb_header(inbuf)) {
2551 DEBUG(10, ("Got invalid SMB header\n"));
2552 return false;
2555 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2556 seqnum)) {
2557 return false;
2559 req.inbuf = inbuf;
2561 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2562 smb_messages[req.cmd].name
2563 ? smb_messages[req.cmd].name : "unknown"));
2565 if (req.cmd != SMBecho) {
2566 return false;
2568 if (req.wct < 1) {
2569 return false;
2572 num_replies = SVAL(req.vwv+0, 0);
2573 if (num_replies != 1) {
2574 /* Not a Windows "Hey, you're still there?" request */
2575 return false;
2578 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2579 1, req.buflen)) {
2580 DEBUG(10, ("create_outbuf failed\n"));
2581 return false;
2583 req.outbuf = (uint8_t *)outbuf;
2585 SSVAL(req.outbuf, smb_vwv0, num_replies);
2587 if (req.buflen > 0) {
2588 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2591 out_len = smb_len(req.outbuf) + 4;
2593 ok = srv_send_smb(req.sconn,
2594 (char *)outbuf,
2595 true, seqnum+1,
2596 false, &req.pcd);
2597 TALLOC_FREE(outbuf);
2598 if (!ok) {
2599 exit(1);
2602 return true;
2605 static void smbd_echo_exit(struct tevent_context *ev,
2606 struct tevent_fd *fde, uint16_t flags,
2607 void *private_data)
2609 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2610 exit(0);
2613 static void smbd_echo_reader(struct tevent_context *ev,
2614 struct tevent_fd *fde, uint16_t flags,
2615 void *private_data)
2617 struct smbd_echo_state *state = talloc_get_type_abort(
2618 private_data, struct smbd_echo_state);
2619 struct smbd_server_connection *sconn = state->sconn;
2620 size_t unread, num_pending;
2621 NTSTATUS status;
2622 struct iovec *tmp;
2623 size_t iov_len;
2624 uint32_t seqnum = 0;
2625 bool reply;
2626 bool ok;
2627 bool encrypted = false;
2629 smb_msleep(1000);
2631 ok = smbd_lock_socket_internal(sconn);
2632 if (!ok) {
2633 DEBUG(0, ("%s: failed to lock socket\n",
2634 __location__));
2635 exit(1);
2638 if (!fd_is_readable(sconn->sock)) {
2639 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2640 (int)sys_getpid()));
2641 ok = smbd_unlock_socket_internal(sconn);
2642 if (!ok) {
2643 DEBUG(1, ("%s: failed to unlock socket in\n",
2644 __location__));
2645 exit(1);
2647 return;
2650 num_pending = talloc_array_length(state->pending);
2651 tmp = talloc_realloc(state, state->pending, struct iovec,
2652 num_pending+1);
2653 if (tmp == NULL) {
2654 DEBUG(1, ("talloc_realloc failed\n"));
2655 exit(1);
2657 state->pending = tmp;
2659 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2661 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2662 (char **)(void *)&state->pending[num_pending].iov_base,
2663 0 /* timeout */,
2664 &unread,
2665 &encrypted,
2666 &iov_len,
2667 &seqnum,
2668 false /* trusted_channel*/);
2669 if (!NT_STATUS_IS_OK(status)) {
2670 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2671 (int)sys_getpid(), nt_errstr(status)));
2672 exit(1);
2674 state->pending[num_pending].iov_len = iov_len;
2676 ok = smbd_unlock_socket_internal(sconn);
2677 if (!ok) {
2678 DEBUG(1, ("%s: failed to unlock socket in\n",
2679 __location__));
2680 exit(1);
2683 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2684 state->pending[num_pending].iov_len,
2685 seqnum);
2686 if (reply) {
2687 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2688 /* no check, shrinking by some bytes does not fail */
2689 state->pending = talloc_realloc(state, state->pending,
2690 struct iovec,
2691 num_pending);
2692 return;
2695 if (state->pending[num_pending].iov_len >= smb_size) {
2697 * place the seqnum in the packet so that the main process
2698 * can reply with signing
2700 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2701 smb_ss_field, seqnum);
2702 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2703 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2706 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2707 smbd_echo_activate_writer(state);
2710 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2711 int parent_pipe)
2713 struct smbd_echo_state *state;
2715 state = talloc_zero(sconn, struct smbd_echo_state);
2716 if (state == NULL) {
2717 DEBUG(1, ("talloc failed\n"));
2718 return;
2720 state->sconn = sconn;
2721 state->parent_pipe = parent_pipe;
2722 state->ev = s3_tevent_context_init(state);
2723 if (state->ev == NULL) {
2724 DEBUG(1, ("tevent_context_init failed\n"));
2725 TALLOC_FREE(state);
2726 return;
2728 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2729 TEVENT_FD_READ, smbd_echo_exit,
2730 state);
2731 if (state->parent_fde == NULL) {
2732 DEBUG(1, ("tevent_add_fd failed\n"));
2733 TALLOC_FREE(state);
2734 return;
2736 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2737 TEVENT_FD_READ, smbd_echo_reader,
2738 state);
2739 if (state->read_fde == NULL) {
2740 DEBUG(1, ("tevent_add_fd failed\n"));
2741 TALLOC_FREE(state);
2742 return;
2745 while (true) {
2746 if (tevent_loop_once(state->ev) == -1) {
2747 DEBUG(1, ("tevent_loop_once failed: %s\n",
2748 strerror(errno)));
2749 break;
2752 TALLOC_FREE(state);
2756 * Handle SMBecho requests in a forked child process
2758 bool fork_echo_handler(struct smbd_server_connection *sconn)
2760 int listener_pipe[2];
2761 int res;
2762 pid_t child;
2764 res = pipe(listener_pipe);
2765 if (res == -1) {
2766 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2767 return false;
2769 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2770 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2771 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2772 goto fail;
2775 child = sys_fork();
2776 if (child == 0) {
2777 NTSTATUS status;
2779 close(listener_pipe[0]);
2780 set_blocking(listener_pipe[1], false);
2782 status = reinit_after_fork(sconn->msg_ctx,
2783 smbd_event_context(),
2784 procid_self(), false);
2785 if (!NT_STATUS_IS_OK(status)) {
2786 DEBUG(1, ("reinit_after_fork failed: %s\n",
2787 nt_errstr(status)));
2788 exit(1);
2790 smbd_echo_loop(sconn, listener_pipe[1]);
2791 exit(0);
2793 close(listener_pipe[1]);
2794 listener_pipe[1] = -1;
2795 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2797 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2800 * Without smb signing this is the same as the normal smbd
2801 * listener. This needs to change once signing comes in.
2803 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2804 sconn,
2805 sconn->smb1.echo_handler.trusted_fd,
2806 EVENT_FD_READ,
2807 smbd_server_echo_handler,
2808 sconn);
2809 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2810 DEBUG(1, ("event_add_fd failed\n"));
2811 goto fail;
2814 return true;
2816 fail:
2817 if (listener_pipe[0] != -1) {
2818 close(listener_pipe[0]);
2820 if (listener_pipe[1] != -1) {
2821 close(listener_pipe[1]);
2823 sconn->smb1.echo_handler.trusted_fd = -1;
2824 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2825 close(sconn->smb1.echo_handler.socket_lock_fd);
2827 sconn->smb1.echo_handler.trusted_fd = -1;
2828 sconn->smb1.echo_handler.socket_lock_fd = -1;
2829 return false;
2832 #if CLUSTER_SUPPORT
2834 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2835 struct sockaddr_storage *srv,
2836 struct sockaddr_storage *clnt)
2838 struct ctdbd_connection *cconn;
2839 char tmp_addr[INET6_ADDRSTRLEN];
2840 char *addr;
2842 cconn = messaging_ctdbd_connection();
2843 if (cconn == NULL) {
2844 return NT_STATUS_NO_MEMORY;
2847 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2848 addr = talloc_strdup(cconn, tmp_addr);
2849 if (addr == NULL) {
2850 return NT_STATUS_NO_MEMORY;
2852 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2855 #endif
2857 /****************************************************************************
2858 Process commands from the client
2859 ****************************************************************************/
2861 void smbd_process(struct smbd_server_connection *sconn)
2863 TALLOC_CTX *frame = talloc_stackframe();
2864 struct sockaddr_storage ss;
2865 struct sockaddr *sa = NULL;
2866 socklen_t sa_socklen;
2867 struct tsocket_address *local_address = NULL;
2868 struct tsocket_address *remote_address = NULL;
2869 const char *remaddr = NULL;
2870 int ret;
2872 if (lp_maxprotocol() == PROTOCOL_SMB2) {
2874 * We're not making the decision here,
2875 * we're just allowing the client
2876 * to decide between SMB1 and SMB2
2877 * with the first negprot
2878 * packet.
2880 sconn->using_smb2 = true;
2883 /* Ensure child is set to blocking mode */
2884 set_blocking(sconn->sock,True);
2886 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2887 set_socket_options(sconn->sock, lp_socket_options());
2889 sa = (struct sockaddr *)(void *)&ss;
2890 sa_socklen = sizeof(ss);
2891 ret = getpeername(sconn->sock, sa, &sa_socklen);
2892 if (ret != 0) {
2893 int level = (errno == ENOTCONN)?2:0;
2894 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2895 exit_server_cleanly("getpeername() failed.\n");
2897 ret = tsocket_address_bsd_from_sockaddr(sconn,
2898 sa, sa_socklen,
2899 &remote_address);
2900 if (ret != 0) {
2901 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2902 __location__, strerror(errno)));
2903 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2906 sa = (struct sockaddr *)(void *)&ss;
2907 sa_socklen = sizeof(ss);
2908 ret = getsockname(sconn->sock, sa, &sa_socklen);
2909 if (ret != 0) {
2910 int level = (errno == ENOTCONN)?2:0;
2911 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2912 exit_server_cleanly("getsockname() failed.\n");
2914 ret = tsocket_address_bsd_from_sockaddr(sconn,
2915 sa, sa_socklen,
2916 &local_address);
2917 if (ret != 0) {
2918 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2919 __location__, strerror(errno)));
2920 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2923 sconn->local_address = local_address;
2924 sconn->remote_address = remote_address;
2926 if (tsocket_address_is_inet(remote_address, "ip")) {
2927 remaddr = tsocket_address_inet_addr_string(
2928 sconn->remote_address,
2929 talloc_tos());
2930 if (remaddr == NULL) {
2933 } else {
2934 remaddr = "0.0.0.0";
2937 /* this is needed so that we get decent entries
2938 in smbstatus for port 445 connects */
2939 set_remote_machine_name(remaddr, false);
2940 reload_services(sconn->msg_ctx, sconn->sock, true);
2943 * Before the first packet, check the global hosts allow/ hosts deny
2944 * parameters before doing any parsing of packets passed to us by the
2945 * client. This prevents attacks on our parsing code from hosts not in
2946 * the hosts allow list.
2949 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2950 sconn->client_id.name,
2951 sconn->client_id.addr)) {
2953 * send a negative session response "not listening on calling
2954 * name"
2956 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2957 DEBUG( 1, ("Connection denied from %s to %s\n",
2958 tsocket_address_string(remote_address, talloc_tos()),
2959 tsocket_address_string(local_address, talloc_tos())));
2960 (void)srv_send_smb(sconn,(char *)buf, false,
2961 0, false, NULL);
2962 exit_server_cleanly("connection denied");
2965 DEBUG(10, ("Connection allowed from %s to %s\n",
2966 tsocket_address_string(remote_address, talloc_tos()),
2967 tsocket_address_string(local_address, talloc_tos())));
2969 init_modules();
2971 smb_perfcount_init();
2973 if (!init_account_policy()) {
2974 exit_server("Could not open account policy tdb.\n");
2977 if (*lp_rootdir()) {
2978 if (chroot(lp_rootdir()) != 0) {
2979 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2980 exit_server("Failed to chroot()");
2982 if (chdir("/") == -1) {
2983 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2984 exit_server("Failed to chroot()");
2986 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2989 if (!srv_init_signing(sconn)) {
2990 exit_server("Failed to init smb_signing");
2993 /* Setup oplocks */
2994 if (!init_oplocks(sconn->msg_ctx))
2995 exit_server("Failed to init oplocks");
2997 /* register our message handlers */
2998 messaging_register(sconn->msg_ctx, NULL,
2999 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3000 messaging_register(sconn->msg_ctx, sconn,
3001 MSG_SMB_RELEASE_IP, msg_release_ip);
3002 messaging_register(sconn->msg_ctx, NULL,
3003 MSG_SMB_CLOSE_FILE, msg_close_file);
3006 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3007 * MSGs to all child processes
3009 messaging_deregister(sconn->msg_ctx,
3010 MSG_DEBUG, NULL);
3011 messaging_register(sconn->msg_ctx, NULL,
3012 MSG_DEBUG, debug_message);
3014 if ((lp_keepalive() != 0)
3015 && !(event_add_idle(smbd_event_context(), NULL,
3016 timeval_set(lp_keepalive(), 0),
3017 "keepalive", keepalive_fn,
3018 NULL))) {
3019 DEBUG(0, ("Could not add keepalive event\n"));
3020 exit(1);
3023 if (!(event_add_idle(smbd_event_context(), NULL,
3024 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3025 "deadtime", deadtime_fn, sconn))) {
3026 DEBUG(0, ("Could not add deadtime event\n"));
3027 exit(1);
3030 if (!(event_add_idle(smbd_event_context(), NULL,
3031 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3032 "housekeeping", housekeeping_fn, sconn))) {
3033 DEBUG(0, ("Could not add housekeeping event\n"));
3034 exit(1);
3037 #ifdef CLUSTER_SUPPORT
3039 if (lp_clustering()) {
3041 * We need to tell ctdb about our client's TCP
3042 * connection, so that for failover ctdbd can send
3043 * tickle acks, triggering a reconnection by the
3044 * client.
3047 struct sockaddr_storage srv, clnt;
3049 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3050 NTSTATUS status;
3051 status = smbd_register_ips(sconn, &srv, &clnt);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3054 nt_errstr(status)));
3056 } else
3058 DEBUG(0,("Unable to get tcp info for "
3059 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3060 strerror(errno)));
3064 #endif
3066 sconn->nbt.got_session = false;
3068 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3070 sconn->smb1.sessions.done_sesssetup = false;
3071 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3072 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3073 /* users from session setup */
3074 sconn->smb1.sessions.session_userlist = NULL;
3075 /* workgroup from session setup. */
3076 sconn->smb1.sessions.session_workgroup = NULL;
3077 /* this holds info on user ids that are already validated for this VC */
3078 sconn->smb1.sessions.validated_users = NULL;
3079 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3080 sconn->smb1.sessions.num_validated_vuids = 0;
3082 conn_init(sconn);
3083 if (!init_dptrs(sconn)) {
3084 exit_server("init_dptrs() failed");
3087 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3088 sconn,
3089 sconn->sock,
3090 EVENT_FD_READ,
3091 smbd_server_connection_handler,
3092 sconn);
3093 if (!sconn->smb1.fde) {
3094 exit_server("failed to create smbd_server_connection fde");
3097 TALLOC_FREE(frame);
3099 while (True) {
3100 NTSTATUS status;
3102 frame = talloc_stackframe_pool(8192);
3104 errno = 0;
3106 status = smbd_server_connection_loop_once(sconn);
3107 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3108 !NT_STATUS_IS_OK(status)) {
3109 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3110 " exiting\n", nt_errstr(status)));
3111 break;
3114 TALLOC_FREE(frame);
3117 exit_server_cleanly(NULL);
3120 bool req_is_in_chain(struct smb_request *req)
3122 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3124 * We're right now handling a subsequent request, so we must
3125 * be in a chain
3127 return true;
3130 if (!is_andx_req(req->cmd)) {
3131 return false;
3134 if (req->wct < 2) {
3136 * Okay, an illegal request, but definitely not chained :-)
3138 return false;
3141 return (CVAL(req->vwv+0, 0) != 0xFF);