s3: Pass smbd_server_connection to srv_free_enc_buffer
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blobc2ce867b6e3ed7ce838fc9d118d27aff8b11a64c
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"
40 extern bool global_machine_password_needs_changing;
42 static void construct_reply_common(struct smb_request *req, const char *inbuf,
43 char *outbuf);
44 static struct pending_message_list *get_deferred_open_message_smb(
45 struct smbd_server_connection *sconn, uint64_t mid);
47 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
49 bool ok;
51 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
52 return true;
55 sconn->smb1.echo_handler.ref_count++;
57 if (sconn->smb1.echo_handler.ref_count > 1) {
58 return true;
61 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
63 do {
64 ok = fcntl_lock(
65 sconn->smb1.echo_handler.socket_lock_fd,
66 SMB_F_SETLKW, 0, 0, F_WRLCK);
67 } while (!ok && (errno == EINTR));
69 if (!ok) {
70 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
71 return false;
74 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
76 return true;
79 void smbd_lock_socket(struct smbd_server_connection *sconn)
81 if (!smbd_lock_socket_internal(sconn)) {
82 exit_server_cleanly("failed to lock socket");
86 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
88 bool ok;
90 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
91 return true;
94 sconn->smb1.echo_handler.ref_count--;
96 if (sconn->smb1.echo_handler.ref_count > 0) {
97 return true;
100 do {
101 ok = fcntl_lock(
102 sconn->smb1.echo_handler.socket_lock_fd,
103 SMB_F_SETLKW, 0, 0, F_UNLCK);
104 } while (!ok && (errno == EINTR));
106 if (!ok) {
107 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
108 return false;
111 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
113 return true;
116 void smbd_unlock_socket(struct smbd_server_connection *sconn)
118 if (!smbd_unlock_socket_internal(sconn)) {
119 exit_server_cleanly("failed to unlock socket");
123 /* Accessor function for smb_read_error for smbd functions. */
125 /****************************************************************************
126 Send an smb to a fd.
127 ****************************************************************************/
129 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
130 bool do_signing, uint32_t seqnum,
131 bool do_encrypt,
132 struct smb_perfcount_data *pcd)
134 size_t len = 0;
135 size_t nwritten=0;
136 ssize_t ret;
137 char *buf_out = buffer;
139 smbd_lock_socket(sconn);
141 if (do_signing) {
142 /* Sign the outgoing packet if required. */
143 srv_calculate_sign_mac(sconn, buf_out, seqnum);
146 if (do_encrypt) {
147 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
148 if (!NT_STATUS_IS_OK(status)) {
149 DEBUG(0, ("send_smb: SMB encryption failed "
150 "on outgoing packet! Error %s\n",
151 nt_errstr(status) ));
152 goto out;
156 len = smb_len(buf_out) + 4;
158 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
159 if (ret <= 0) {
161 char addr[INET6_ADDRSTRLEN];
163 * Try and give an error message saying what
164 * client failed.
166 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
167 (int)sys_getpid(), (int)len,
168 get_peer_addr(sconn->sock, addr, sizeof(addr)),
169 (int)ret, strerror(errno) ));
171 srv_free_enc_buffer(sconn, buf_out);
172 goto out;
175 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
176 srv_free_enc_buffer(sconn, buf_out);
177 out:
178 SMB_PERFCOUNT_END(pcd);
180 smbd_unlock_socket(sconn);
181 return true;
184 /*******************************************************************
185 Setup the word count and byte count for a smb message.
186 ********************************************************************/
188 int srv_set_message(char *buf,
189 int num_words,
190 int num_bytes,
191 bool zero)
193 if (zero && (num_words || num_bytes)) {
194 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
196 SCVAL(buf,smb_wct,num_words);
197 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
198 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
199 return (smb_size + num_words*2 + num_bytes);
202 static bool valid_smb_header(struct smbd_server_connection *sconn,
203 const uint8_t *inbuf)
205 if (is_encrypted_packet(sconn, inbuf)) {
206 return true;
209 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
210 * but it just looks weird to call strncmp for this one.
212 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
215 /* Socket functions for smbd packet processing. */
217 static bool valid_packet_size(size_t len)
220 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
221 * of header. Don't print the error if this fits.... JRA.
224 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
225 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
226 (unsigned long)len));
227 return false;
229 return true;
232 static NTSTATUS read_packet_remainder(int fd, char *buffer,
233 unsigned int timeout, ssize_t len)
235 NTSTATUS status;
237 if (len <= 0) {
238 return NT_STATUS_OK;
241 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
242 if (!NT_STATUS_IS_OK(status)) {
243 char addr[INET6_ADDRSTRLEN];
244 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
245 "error = %s.\n",
246 get_peer_addr(fd, addr, sizeof(addr)),
247 nt_errstr(status)));
249 return status;
252 /****************************************************************************
253 Attempt a zerocopy writeX read. We know here that len > smb_size-4
254 ****************************************************************************/
257 * Unfortunately, earlier versions of smbclient/libsmbclient
258 * don't send this "standard" writeX header. I've fixed this
259 * for 3.2 but we'll use the old method with earlier versions.
260 * Windows and CIFSFS at least use this standard size. Not
261 * sure about MacOSX.
264 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
265 (2*14) + /* word count (including bcc) */ \
266 1 /* pad byte */)
268 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
269 const char lenbuf[4],
270 struct smbd_server_connection *sconn,
271 int sock,
272 char **buffer,
273 unsigned int timeout,
274 size_t *p_unread,
275 size_t *len_ret)
277 /* Size of a WRITEX call (+4 byte len). */
278 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
279 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
280 ssize_t toread;
281 NTSTATUS status;
283 memcpy(writeX_header, lenbuf, 4);
285 status = read_fd_with_timeout(
286 sock, writeX_header + 4,
287 STANDARD_WRITE_AND_X_HEADER_SIZE,
288 STANDARD_WRITE_AND_X_HEADER_SIZE,
289 timeout, NULL);
291 if (!NT_STATUS_IS_OK(status)) {
292 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
293 "error = %s.\n",
294 tsocket_address_string(sconn->remote_address,
295 talloc_tos()),
296 nt_errstr(status)));
297 return status;
301 * Ok - now try and see if this is a possible
302 * valid writeX call.
305 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
307 * If the data offset is beyond what
308 * we've read, drain the extra bytes.
310 uint16_t doff = SVAL(writeX_header,smb_vwv11);
311 ssize_t newlen;
313 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
314 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
315 if (drain_socket(sock, drain) != drain) {
316 smb_panic("receive_smb_raw_talloc_partial_read:"
317 " failed to drain pending bytes");
319 } else {
320 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
323 /* Spoof down the length and null out the bcc. */
324 set_message_bcc(writeX_header, 0);
325 newlen = smb_len(writeX_header);
327 /* Copy the header we've written. */
329 *buffer = (char *)talloc_memdup(mem_ctx,
330 writeX_header,
331 sizeof(writeX_header));
333 if (*buffer == NULL) {
334 DEBUG(0, ("Could not allocate inbuf of length %d\n",
335 (int)sizeof(writeX_header)));
336 return NT_STATUS_NO_MEMORY;
339 /* Work out the remaining bytes. */
340 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
341 *len_ret = newlen + 4;
342 return NT_STATUS_OK;
345 if (!valid_packet_size(len)) {
346 return NT_STATUS_INVALID_PARAMETER;
350 * Not a valid writeX call. Just do the standard
351 * talloc and return.
354 *buffer = talloc_array(mem_ctx, char, len+4);
356 if (*buffer == NULL) {
357 DEBUG(0, ("Could not allocate inbuf of length %d\n",
358 (int)len+4));
359 return NT_STATUS_NO_MEMORY;
362 /* Copy in what we already read. */
363 memcpy(*buffer,
364 writeX_header,
365 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
366 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
368 if(toread > 0) {
369 status = read_packet_remainder(
370 sock,
371 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
372 timeout, toread);
374 if (!NT_STATUS_IS_OK(status)) {
375 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
376 nt_errstr(status)));
377 return status;
381 *len_ret = len + 4;
382 return NT_STATUS_OK;
385 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
386 struct smbd_server_connection *sconn,
387 int sock,
388 char **buffer, unsigned int timeout,
389 size_t *p_unread, size_t *plen)
391 char lenbuf[4];
392 size_t len;
393 int min_recv_size = lp_min_receive_file_size();
394 NTSTATUS status;
396 *p_unread = 0;
398 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
399 &len);
400 if (!NT_STATUS_IS_OK(status)) {
401 return status;
404 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
405 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
406 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
407 !srv_is_signing_active(sconn) &&
408 sconn->smb1.echo_handler.trusted_fde == NULL) {
410 return receive_smb_raw_talloc_partial_read(
411 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
412 p_unread, plen);
415 if (!valid_packet_size(len)) {
416 return NT_STATUS_INVALID_PARAMETER;
420 * The +4 here can't wrap, we've checked the length above already.
423 *buffer = talloc_array(mem_ctx, char, len+4);
425 if (*buffer == NULL) {
426 DEBUG(0, ("Could not allocate inbuf of length %d\n",
427 (int)len+4));
428 return NT_STATUS_NO_MEMORY;
431 memcpy(*buffer, lenbuf, sizeof(lenbuf));
433 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
434 if (!NT_STATUS_IS_OK(status)) {
435 return status;
438 *plen = len + 4;
439 return NT_STATUS_OK;
442 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
443 struct smbd_server_connection *sconn,
444 int sock,
445 char **buffer, unsigned int timeout,
446 size_t *p_unread, bool *p_encrypted,
447 size_t *p_len,
448 uint32_t *seqnum,
449 bool trusted_channel)
451 size_t len = 0;
452 NTSTATUS status;
454 *p_encrypted = false;
456 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
457 p_unread, &len);
458 if (!NT_STATUS_IS_OK(status)) {
459 DEBUG(1, ("read_smb_length_return_keepalive failed for "
460 "client %s read error = %s.\n",
461 tsocket_address_string(sconn->remote_address,
462 talloc_tos()),
463 nt_errstr(status)));
464 return status;
467 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
468 status = srv_decrypt_buffer(*buffer);
469 if (!NT_STATUS_IS_OK(status)) {
470 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
471 "incoming packet! Error %s\n",
472 nt_errstr(status) ));
473 return status;
475 *p_encrypted = true;
478 /* Check the incoming SMB signature. */
479 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
480 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
481 "incoming packet!\n"));
482 return NT_STATUS_INVALID_NETWORK_RESPONSE;
485 *p_len = len;
486 return NT_STATUS_OK;
490 * Initialize a struct smb_request from an inbuf
493 static bool init_smb_request(struct smb_request *req,
494 struct smbd_server_connection *sconn,
495 const uint8 *inbuf,
496 size_t unread_bytes, bool encrypted,
497 uint32_t seqnum)
499 size_t req_size = smb_len(inbuf) + 4;
500 /* Ensure we have at least smb_size bytes. */
501 if (req_size < smb_size) {
502 DEBUG(0,("init_smb_request: invalid request size %u\n",
503 (unsigned int)req_size ));
504 return false;
506 req->cmd = CVAL(inbuf, smb_com);
507 req->flags2 = SVAL(inbuf, smb_flg2);
508 req->smbpid = SVAL(inbuf, smb_pid);
509 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
510 req->seqnum = seqnum;
511 req->vuid = SVAL(inbuf, smb_uid);
512 req->tid = SVAL(inbuf, smb_tid);
513 req->wct = CVAL(inbuf, smb_wct);
514 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
515 req->buflen = smb_buflen(inbuf);
516 req->buf = (const uint8_t *)smb_buf_const(inbuf);
517 req->unread_bytes = unread_bytes;
518 req->encrypted = encrypted;
519 req->sconn = sconn;
520 req->conn = conn_find(sconn,req->tid);
521 req->chain_fsp = NULL;
522 req->chain_outbuf = NULL;
523 req->done = false;
524 req->smb2req = NULL;
525 smb_init_perfcount_data(&req->pcd);
527 /* Ensure we have at least wct words and 2 bytes of bcc. */
528 if (smb_size + req->wct*2 > req_size) {
529 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
530 (unsigned int)req->wct,
531 (unsigned int)req_size));
532 return false;
534 /* Ensure bcc is correct. */
535 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
536 DEBUG(0,("init_smb_request: invalid bcc number %u "
537 "(wct = %u, size %u)\n",
538 (unsigned int)req->buflen,
539 (unsigned int)req->wct,
540 (unsigned int)req_size));
541 return false;
544 req->outbuf = NULL;
545 return true;
548 static void process_smb(struct smbd_server_connection *conn,
549 uint8_t *inbuf, size_t nread, size_t unread_bytes,
550 uint32_t seqnum, bool encrypted,
551 struct smb_perfcount_data *deferred_pcd);
553 static void smbd_deferred_open_timer(struct event_context *ev,
554 struct timed_event *te,
555 struct timeval _tval,
556 void *private_data)
558 struct pending_message_list *msg = talloc_get_type(private_data,
559 struct pending_message_list);
560 TALLOC_CTX *mem_ctx = talloc_tos();
561 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
562 uint8_t *inbuf;
564 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
565 msg->buf.length);
566 if (inbuf == NULL) {
567 exit_server("smbd_deferred_open_timer: talloc failed\n");
568 return;
571 /* We leave this message on the queue so the open code can
572 know this is a retry. */
573 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
574 (unsigned long long)mid ));
576 /* Mark the message as processed so this is not
577 * re-processed in error. */
578 msg->processed = true;
580 process_smb(smbd_server_conn, inbuf,
581 msg->buf.length, 0,
582 msg->seqnum, msg->encrypted, &msg->pcd);
584 /* If it's still there and was processed, remove it. */
585 msg = get_deferred_open_message_smb(smbd_server_conn, mid);
586 if (msg && msg->processed) {
587 remove_deferred_open_message_smb(smbd_server_conn, mid);
591 /****************************************************************************
592 Function to push a message onto the tail of a linked list of smb messages ready
593 for processing.
594 ****************************************************************************/
596 static bool push_queued_message(struct smb_request *req,
597 struct timeval request_time,
598 struct timeval end_time,
599 char *private_data, size_t private_len)
601 int msg_len = smb_len(req->inbuf) + 4;
602 struct pending_message_list *msg;
604 msg = talloc_zero(NULL, struct pending_message_list);
606 if(msg == NULL) {
607 DEBUG(0,("push_message: malloc fail (1)\n"));
608 return False;
611 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
612 if(msg->buf.data == NULL) {
613 DEBUG(0,("push_message: malloc fail (2)\n"));
614 TALLOC_FREE(msg);
615 return False;
618 msg->request_time = request_time;
619 msg->seqnum = req->seqnum;
620 msg->encrypted = req->encrypted;
621 msg->processed = false;
622 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
624 if (private_data) {
625 msg->private_data = data_blob_talloc(msg, private_data,
626 private_len);
627 if (msg->private_data.data == NULL) {
628 DEBUG(0,("push_message: malloc fail (3)\n"));
629 TALLOC_FREE(msg);
630 return False;
634 msg->te = event_add_timed(server_event_context(),
635 msg,
636 end_time,
637 smbd_deferred_open_timer,
638 msg);
639 if (!msg->te) {
640 DEBUG(0,("push_message: event_add_timed failed\n"));
641 TALLOC_FREE(msg);
642 return false;
645 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
646 struct pending_message_list *);
648 DEBUG(10,("push_message: pushed message length %u on "
649 "deferred_open_queue\n", (unsigned int)msg_len));
651 return True;
654 /****************************************************************************
655 Function to delete a sharing violation open message by mid.
656 ****************************************************************************/
658 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
659 uint64_t mid)
661 struct pending_message_list *pml;
663 if (sconn->using_smb2) {
664 remove_deferred_open_message_smb2(sconn, mid);
665 return;
668 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
669 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
670 DEBUG(10,("remove_deferred_open_message_smb: "
671 "deleting mid %llu len %u\n",
672 (unsigned long long)mid,
673 (unsigned int)pml->buf.length ));
674 DLIST_REMOVE(sconn->deferred_open_queue, pml);
675 TALLOC_FREE(pml);
676 return;
681 /****************************************************************************
682 Move a sharing violation open retry message to the front of the list and
683 schedule it for immediate processing.
684 ****************************************************************************/
686 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
687 uint64_t mid)
689 struct pending_message_list *pml;
690 int i = 0;
692 if (sconn->using_smb2) {
693 schedule_deferred_open_message_smb2(sconn, mid);
694 return;
697 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
698 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
700 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
701 "msg_mid = %llu\n",
702 i++,
703 (unsigned long long)msg_mid ));
705 if (mid == msg_mid) {
706 struct timed_event *te;
708 if (pml->processed) {
709 /* A processed message should not be
710 * rescheduled. */
711 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
712 "message mid %llu was already processed\n",
713 (unsigned long long)msg_mid ));
714 continue;
717 DEBUG(10,("schedule_deferred_open_message_smb: "
718 "scheduling mid %llu\n",
719 (unsigned long long)mid ));
721 te = event_add_timed(server_event_context(),
722 pml,
723 timeval_zero(),
724 smbd_deferred_open_timer,
725 pml);
726 if (!te) {
727 DEBUG(10,("schedule_deferred_open_message_smb: "
728 "event_add_timed() failed, "
729 "skipping mid %llu\n",
730 (unsigned long long)msg_mid ));
733 TALLOC_FREE(pml->te);
734 pml->te = te;
735 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
736 return;
740 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
741 "find message mid %llu\n",
742 (unsigned long long)mid ));
745 /****************************************************************************
746 Return true if this mid is on the deferred queue and was not yet processed.
747 ****************************************************************************/
749 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
751 struct pending_message_list *pml;
753 if (sconn->using_smb2) {
754 return open_was_deferred_smb2(sconn, mid);
757 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
758 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
759 return True;
762 return False;
765 /****************************************************************************
766 Return the message queued by this mid.
767 ****************************************************************************/
769 static struct pending_message_list *get_deferred_open_message_smb(
770 struct smbd_server_connection *sconn, uint64_t mid)
772 struct pending_message_list *pml;
774 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
775 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
776 return pml;
779 return NULL;
782 /****************************************************************************
783 Get the state data queued by this mid.
784 ****************************************************************************/
786 bool get_deferred_open_message_state(struct smb_request *smbreq,
787 struct timeval *p_request_time,
788 void **pp_state)
790 struct pending_message_list *pml;
792 if (smbd_server_conn->using_smb2) {
793 return get_deferred_open_message_state_smb2(smbreq->smb2req,
794 p_request_time,
795 pp_state);
798 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
799 if (!pml) {
800 return false;
802 if (p_request_time) {
803 *p_request_time = pml->request_time;
805 if (pp_state) {
806 *pp_state = (void *)pml->private_data.data;
808 return true;
811 /****************************************************************************
812 Function to push a deferred open smb message onto a linked list of local smb
813 messages ready for processing.
814 ****************************************************************************/
816 bool push_deferred_open_message_smb(struct smb_request *req,
817 struct timeval request_time,
818 struct timeval timeout,
819 struct file_id id,
820 char *private_data, size_t priv_len)
822 struct timeval end_time;
824 if (req->smb2req) {
825 return push_deferred_open_message_smb2(req->smb2req,
826 request_time,
827 timeout,
829 private_data,
830 priv_len);
833 if (req->unread_bytes) {
834 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
835 "unread_bytes = %u\n",
836 (unsigned int)req->unread_bytes ));
837 smb_panic("push_deferred_open_message_smb: "
838 "logic error unread_bytes != 0" );
841 end_time = timeval_sum(&request_time, &timeout);
843 DEBUG(10,("push_deferred_open_message_smb: pushing message "
844 "len %u mid %llu timeout time [%u.%06u]\n",
845 (unsigned int) smb_len(req->inbuf)+4,
846 (unsigned long long)req->mid,
847 (unsigned int)end_time.tv_sec,
848 (unsigned int)end_time.tv_usec));
850 return push_queued_message(req, request_time, end_time,
851 private_data, priv_len);
854 static void smbd_sig_term_handler(struct tevent_context *ev,
855 struct tevent_signal *se,
856 int signum,
857 int count,
858 void *siginfo,
859 void *private_data)
861 exit_server_cleanly("termination signal");
864 void smbd_setup_sig_term_handler(void)
866 struct tevent_signal *se;
868 se = tevent_add_signal(server_event_context(),
869 server_event_context(),
870 SIGTERM, 0,
871 smbd_sig_term_handler,
872 NULL);
873 if (!se) {
874 exit_server("failed to setup SIGTERM handler");
878 static void smbd_sig_hup_handler(struct tevent_context *ev,
879 struct tevent_signal *se,
880 int signum,
881 int count,
882 void *siginfo,
883 void *private_data)
885 struct messaging_context *msg_ctx = talloc_get_type_abort(
886 private_data, struct messaging_context);
887 change_to_root_user();
888 DEBUG(1,("Reloading services after SIGHUP\n"));
889 reload_services(msg_ctx, smbd_server_conn->sock, False);
890 if (am_parent) {
891 printing_subsystem_update(ev, msg_ctx, true);
895 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
896 struct messaging_context *msg_ctx)
898 struct tevent_signal *se;
900 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
901 msg_ctx);
902 if (!se) {
903 exit_server("failed to setup SIGHUP handler");
907 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
908 struct smbd_server_connection *conn)
910 int timeout;
911 int num_pfds = 0;
912 int ret;
913 bool retry;
915 timeout = SMBD_SELECT_TIMEOUT * 1000;
918 * Are there any timed events waiting ? If so, ensure we don't
919 * select for longer than it would take to wait for them.
922 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
924 /* Process a signal and timed events now... */
925 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
926 return NT_STATUS_RETRY;
930 int sav;
931 START_PROFILE(smbd_idle);
933 ret = sys_poll(conn->pfds, num_pfds, timeout);
934 sav = errno;
936 END_PROFILE(smbd_idle);
937 errno = sav;
940 if (ret == -1) {
941 if (errno == EINTR) {
942 return NT_STATUS_RETRY;
944 return map_nt_error_from_unix(errno);
947 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
948 if (retry) {
949 return NT_STATUS_RETRY;
952 /* Did we timeout ? */
953 if (ret == 0) {
954 return NT_STATUS_RETRY;
957 /* should not be reached */
958 return NT_STATUS_INTERNAL_ERROR;
962 * Only allow 5 outstanding trans requests. We're allocating memory, so
963 * prevent a DoS.
966 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
968 int count = 0;
969 for (; list != NULL; list = list->next) {
971 if (list->mid == mid) {
972 return NT_STATUS_INVALID_PARAMETER;
975 count += 1;
977 if (count > 5) {
978 return NT_STATUS_INSUFFICIENT_RESOURCES;
981 return NT_STATUS_OK;
985 These flags determine some of the permissions required to do an operation
987 Note that I don't set NEED_WRITE on some write operations because they
988 are used by some brain-dead clients when printing, and I don't want to
989 force write permissions on print services.
991 #define AS_USER (1<<0)
992 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
993 #define TIME_INIT (1<<2)
994 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
995 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
996 #define DO_CHDIR (1<<6)
999 define a list of possible SMB messages and their corresponding
1000 functions. Any message that has a NULL function is unimplemented -
1001 please feel free to contribute implementations!
1003 static const struct smb_message_struct {
1004 const char *name;
1005 void (*fn)(struct smb_request *req);
1006 int flags;
1007 } smb_messages[256] = {
1009 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1010 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1011 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1012 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1013 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1014 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1015 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1016 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1017 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1018 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1019 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1020 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1021 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1022 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1023 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1024 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1025 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1026 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1027 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1028 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1029 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1030 /* 0x15 */ { NULL, NULL, 0 },
1031 /* 0x16 */ { NULL, NULL, 0 },
1032 /* 0x17 */ { NULL, NULL, 0 },
1033 /* 0x18 */ { NULL, NULL, 0 },
1034 /* 0x19 */ { NULL, NULL, 0 },
1035 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1036 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1037 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1038 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1039 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1040 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1041 /* 0x20 */ { "SMBwritec", NULL,0},
1042 /* 0x21 */ { NULL, NULL, 0 },
1043 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1044 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1045 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1046 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1047 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1048 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1049 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1050 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1051 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1052 /* 0x2b */ { "SMBecho",reply_echo,0},
1053 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1054 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1055 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1056 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1057 /* 0x30 */ { NULL, NULL, 0 },
1058 /* 0x31 */ { NULL, NULL, 0 },
1059 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1060 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1061 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1062 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1063 /* 0x36 */ { NULL, NULL, 0 },
1064 /* 0x37 */ { NULL, NULL, 0 },
1065 /* 0x38 */ { NULL, NULL, 0 },
1066 /* 0x39 */ { NULL, NULL, 0 },
1067 /* 0x3a */ { NULL, NULL, 0 },
1068 /* 0x3b */ { NULL, NULL, 0 },
1069 /* 0x3c */ { NULL, NULL, 0 },
1070 /* 0x3d */ { NULL, NULL, 0 },
1071 /* 0x3e */ { NULL, NULL, 0 },
1072 /* 0x3f */ { NULL, NULL, 0 },
1073 /* 0x40 */ { NULL, NULL, 0 },
1074 /* 0x41 */ { NULL, NULL, 0 },
1075 /* 0x42 */ { NULL, NULL, 0 },
1076 /* 0x43 */ { NULL, NULL, 0 },
1077 /* 0x44 */ { NULL, NULL, 0 },
1078 /* 0x45 */ { NULL, NULL, 0 },
1079 /* 0x46 */ { NULL, NULL, 0 },
1080 /* 0x47 */ { NULL, NULL, 0 },
1081 /* 0x48 */ { NULL, NULL, 0 },
1082 /* 0x49 */ { NULL, NULL, 0 },
1083 /* 0x4a */ { NULL, NULL, 0 },
1084 /* 0x4b */ { NULL, NULL, 0 },
1085 /* 0x4c */ { NULL, NULL, 0 },
1086 /* 0x4d */ { NULL, NULL, 0 },
1087 /* 0x4e */ { NULL, NULL, 0 },
1088 /* 0x4f */ { NULL, NULL, 0 },
1089 /* 0x50 */ { NULL, NULL, 0 },
1090 /* 0x51 */ { NULL, NULL, 0 },
1091 /* 0x52 */ { NULL, NULL, 0 },
1092 /* 0x53 */ { NULL, NULL, 0 },
1093 /* 0x54 */ { NULL, NULL, 0 },
1094 /* 0x55 */ { NULL, NULL, 0 },
1095 /* 0x56 */ { NULL, NULL, 0 },
1096 /* 0x57 */ { NULL, NULL, 0 },
1097 /* 0x58 */ { NULL, NULL, 0 },
1098 /* 0x59 */ { NULL, NULL, 0 },
1099 /* 0x5a */ { NULL, NULL, 0 },
1100 /* 0x5b */ { NULL, NULL, 0 },
1101 /* 0x5c */ { NULL, NULL, 0 },
1102 /* 0x5d */ { NULL, NULL, 0 },
1103 /* 0x5e */ { NULL, NULL, 0 },
1104 /* 0x5f */ { NULL, NULL, 0 },
1105 /* 0x60 */ { NULL, NULL, 0 },
1106 /* 0x61 */ { NULL, NULL, 0 },
1107 /* 0x62 */ { NULL, NULL, 0 },
1108 /* 0x63 */ { NULL, NULL, 0 },
1109 /* 0x64 */ { NULL, NULL, 0 },
1110 /* 0x65 */ { NULL, NULL, 0 },
1111 /* 0x66 */ { NULL, NULL, 0 },
1112 /* 0x67 */ { NULL, NULL, 0 },
1113 /* 0x68 */ { NULL, NULL, 0 },
1114 /* 0x69 */ { NULL, NULL, 0 },
1115 /* 0x6a */ { NULL, NULL, 0 },
1116 /* 0x6b */ { NULL, NULL, 0 },
1117 /* 0x6c */ { NULL, NULL, 0 },
1118 /* 0x6d */ { NULL, NULL, 0 },
1119 /* 0x6e */ { NULL, NULL, 0 },
1120 /* 0x6f */ { NULL, NULL, 0 },
1121 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1122 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1123 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1124 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1125 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1126 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1127 /* 0x76 */ { NULL, NULL, 0 },
1128 /* 0x77 */ { NULL, NULL, 0 },
1129 /* 0x78 */ { NULL, NULL, 0 },
1130 /* 0x79 */ { NULL, NULL, 0 },
1131 /* 0x7a */ { NULL, NULL, 0 },
1132 /* 0x7b */ { NULL, NULL, 0 },
1133 /* 0x7c */ { NULL, NULL, 0 },
1134 /* 0x7d */ { NULL, NULL, 0 },
1135 /* 0x7e */ { NULL, NULL, 0 },
1136 /* 0x7f */ { NULL, NULL, 0 },
1137 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1138 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1139 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1140 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1141 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1142 /* 0x85 */ { NULL, NULL, 0 },
1143 /* 0x86 */ { NULL, NULL, 0 },
1144 /* 0x87 */ { NULL, NULL, 0 },
1145 /* 0x88 */ { NULL, NULL, 0 },
1146 /* 0x89 */ { NULL, NULL, 0 },
1147 /* 0x8a */ { NULL, NULL, 0 },
1148 /* 0x8b */ { NULL, NULL, 0 },
1149 /* 0x8c */ { NULL, NULL, 0 },
1150 /* 0x8d */ { NULL, NULL, 0 },
1151 /* 0x8e */ { NULL, NULL, 0 },
1152 /* 0x8f */ { NULL, NULL, 0 },
1153 /* 0x90 */ { NULL, NULL, 0 },
1154 /* 0x91 */ { NULL, NULL, 0 },
1155 /* 0x92 */ { NULL, NULL, 0 },
1156 /* 0x93 */ { NULL, NULL, 0 },
1157 /* 0x94 */ { NULL, NULL, 0 },
1158 /* 0x95 */ { NULL, NULL, 0 },
1159 /* 0x96 */ { NULL, NULL, 0 },
1160 /* 0x97 */ { NULL, NULL, 0 },
1161 /* 0x98 */ { NULL, NULL, 0 },
1162 /* 0x99 */ { NULL, NULL, 0 },
1163 /* 0x9a */ { NULL, NULL, 0 },
1164 /* 0x9b */ { NULL, NULL, 0 },
1165 /* 0x9c */ { NULL, NULL, 0 },
1166 /* 0x9d */ { NULL, NULL, 0 },
1167 /* 0x9e */ { NULL, NULL, 0 },
1168 /* 0x9f */ { NULL, NULL, 0 },
1169 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1170 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1171 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1172 /* 0xa3 */ { NULL, NULL, 0 },
1173 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1174 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1175 /* 0xa6 */ { NULL, NULL, 0 },
1176 /* 0xa7 */ { NULL, NULL, 0 },
1177 /* 0xa8 */ { NULL, NULL, 0 },
1178 /* 0xa9 */ { NULL, NULL, 0 },
1179 /* 0xaa */ { NULL, NULL, 0 },
1180 /* 0xab */ { NULL, NULL, 0 },
1181 /* 0xac */ { NULL, NULL, 0 },
1182 /* 0xad */ { NULL, NULL, 0 },
1183 /* 0xae */ { NULL, NULL, 0 },
1184 /* 0xaf */ { NULL, NULL, 0 },
1185 /* 0xb0 */ { NULL, NULL, 0 },
1186 /* 0xb1 */ { NULL, NULL, 0 },
1187 /* 0xb2 */ { NULL, NULL, 0 },
1188 /* 0xb3 */ { NULL, NULL, 0 },
1189 /* 0xb4 */ { NULL, NULL, 0 },
1190 /* 0xb5 */ { NULL, NULL, 0 },
1191 /* 0xb6 */ { NULL, NULL, 0 },
1192 /* 0xb7 */ { NULL, NULL, 0 },
1193 /* 0xb8 */ { NULL, NULL, 0 },
1194 /* 0xb9 */ { NULL, NULL, 0 },
1195 /* 0xba */ { NULL, NULL, 0 },
1196 /* 0xbb */ { NULL, NULL, 0 },
1197 /* 0xbc */ { NULL, NULL, 0 },
1198 /* 0xbd */ { NULL, NULL, 0 },
1199 /* 0xbe */ { NULL, NULL, 0 },
1200 /* 0xbf */ { NULL, NULL, 0 },
1201 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1202 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1203 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1204 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1205 /* 0xc4 */ { NULL, NULL, 0 },
1206 /* 0xc5 */ { NULL, NULL, 0 },
1207 /* 0xc6 */ { NULL, NULL, 0 },
1208 /* 0xc7 */ { NULL, NULL, 0 },
1209 /* 0xc8 */ { NULL, NULL, 0 },
1210 /* 0xc9 */ { NULL, NULL, 0 },
1211 /* 0xca */ { NULL, NULL, 0 },
1212 /* 0xcb */ { NULL, NULL, 0 },
1213 /* 0xcc */ { NULL, NULL, 0 },
1214 /* 0xcd */ { NULL, NULL, 0 },
1215 /* 0xce */ { NULL, NULL, 0 },
1216 /* 0xcf */ { NULL, NULL, 0 },
1217 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1218 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1219 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1220 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1221 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1222 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1223 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1224 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1225 /* 0xd8 */ { NULL, NULL, 0 },
1226 /* 0xd9 */ { NULL, NULL, 0 },
1227 /* 0xda */ { NULL, NULL, 0 },
1228 /* 0xdb */ { NULL, NULL, 0 },
1229 /* 0xdc */ { NULL, NULL, 0 },
1230 /* 0xdd */ { NULL, NULL, 0 },
1231 /* 0xde */ { NULL, NULL, 0 },
1232 /* 0xdf */ { NULL, NULL, 0 },
1233 /* 0xe0 */ { NULL, NULL, 0 },
1234 /* 0xe1 */ { NULL, NULL, 0 },
1235 /* 0xe2 */ { NULL, NULL, 0 },
1236 /* 0xe3 */ { NULL, NULL, 0 },
1237 /* 0xe4 */ { NULL, NULL, 0 },
1238 /* 0xe5 */ { NULL, NULL, 0 },
1239 /* 0xe6 */ { NULL, NULL, 0 },
1240 /* 0xe7 */ { NULL, NULL, 0 },
1241 /* 0xe8 */ { NULL, NULL, 0 },
1242 /* 0xe9 */ { NULL, NULL, 0 },
1243 /* 0xea */ { NULL, NULL, 0 },
1244 /* 0xeb */ { NULL, NULL, 0 },
1245 /* 0xec */ { NULL, NULL, 0 },
1246 /* 0xed */ { NULL, NULL, 0 },
1247 /* 0xee */ { NULL, NULL, 0 },
1248 /* 0xef */ { NULL, NULL, 0 },
1249 /* 0xf0 */ { NULL, NULL, 0 },
1250 /* 0xf1 */ { NULL, NULL, 0 },
1251 /* 0xf2 */ { NULL, NULL, 0 },
1252 /* 0xf3 */ { NULL, NULL, 0 },
1253 /* 0xf4 */ { NULL, NULL, 0 },
1254 /* 0xf5 */ { NULL, NULL, 0 },
1255 /* 0xf6 */ { NULL, NULL, 0 },
1256 /* 0xf7 */ { NULL, NULL, 0 },
1257 /* 0xf8 */ { NULL, NULL, 0 },
1258 /* 0xf9 */ { NULL, NULL, 0 },
1259 /* 0xfa */ { NULL, NULL, 0 },
1260 /* 0xfb */ { NULL, NULL, 0 },
1261 /* 0xfc */ { NULL, NULL, 0 },
1262 /* 0xfd */ { NULL, NULL, 0 },
1263 /* 0xfe */ { NULL, NULL, 0 },
1264 /* 0xff */ { NULL, NULL, 0 }
1268 /*******************************************************************
1269 allocate and initialize a reply packet
1270 ********************************************************************/
1272 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1273 const char *inbuf, char **outbuf, uint8_t num_words,
1274 uint32_t num_bytes)
1277 * Protect against integer wrap
1279 if ((num_bytes > 0xffffff)
1280 || ((num_bytes + smb_size + num_words*2) > 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);
1289 *outbuf = talloc_array(mem_ctx, char,
1290 smb_size + num_words*2 + num_bytes);
1291 if (*outbuf == NULL) {
1292 return false;
1295 construct_reply_common(req, inbuf, *outbuf);
1296 srv_set_message(*outbuf, num_words, num_bytes, false);
1298 * Zero out the word area, the caller has to take care of the bcc area
1299 * himself
1301 if (num_words != 0) {
1302 memset(*outbuf + smb_vwv0, 0, num_words*2);
1305 return true;
1308 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1310 char *outbuf;
1311 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1312 num_bytes)) {
1313 smb_panic("could not allocate output buffer\n");
1315 req->outbuf = (uint8_t *)outbuf;
1319 /*******************************************************************
1320 Dump a packet to a file.
1321 ********************************************************************/
1323 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1325 int fd, i;
1326 char *fname = NULL;
1327 if (DEBUGLEVEL < 50) {
1328 return;
1331 if (len < 4) len = smb_len(data)+4;
1332 for (i=1;i<100;i++) {
1333 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1334 type ? "req" : "resp") == -1) {
1335 return;
1337 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1338 if (fd != -1 || errno != EEXIST) break;
1340 if (fd != -1) {
1341 ssize_t ret = write(fd, data, len);
1342 if (ret != len)
1343 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1344 close(fd);
1345 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1347 SAFE_FREE(fname);
1350 /****************************************************************************
1351 Prepare everything for calling the actual request function, and potentially
1352 call the request function via the "new" interface.
1354 Return False if the "legacy" function needs to be called, everything is
1355 prepared.
1357 Return True if we're done.
1359 I know this API sucks, but it is the one with the least code change I could
1360 find.
1361 ****************************************************************************/
1363 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1365 int flags;
1366 uint16 session_tag;
1367 connection_struct *conn = NULL;
1368 struct smbd_server_connection *sconn = req->sconn;
1369 char *raddr;
1371 errno = 0;
1373 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1374 * so subtract 4 from it. */
1375 if (!valid_smb_header(sconn, req->inbuf)
1376 || (size < (smb_size - 4))) {
1377 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1378 smb_len(req->inbuf)));
1379 exit_server_cleanly("Non-SMB packet");
1382 if (smb_messages[type].fn == NULL) {
1383 DEBUG(0,("Unknown message type %d!\n",type));
1384 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1385 reply_unknown_new(req, type);
1386 return NULL;
1389 flags = smb_messages[type].flags;
1391 /* In share mode security we must ignore the vuid. */
1392 session_tag = (lp_security() == SEC_SHARE)
1393 ? UID_FIELD_INVALID : req->vuid;
1394 conn = req->conn;
1396 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1397 (int)sys_getpid(), (unsigned long)conn));
1399 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1401 /* Ensure this value is replaced in the incoming packet. */
1402 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1405 * Ensure the correct username is in current_user_info. This is a
1406 * really ugly bugfix for problems with multiple session_setup_and_X's
1407 * being done and allowing %U and %G substitutions to work correctly.
1408 * There is a reason this code is done here, don't move it unless you
1409 * know what you're doing... :-).
1410 * JRA.
1413 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1414 user_struct *vuser = NULL;
1416 sconn->smb1.sessions.last_session_tag = session_tag;
1417 if(session_tag != UID_FIELD_INVALID) {
1418 vuser = get_valid_user_struct(sconn, session_tag);
1419 if (vuser) {
1420 set_current_user_info(
1421 vuser->session_info->unix_info->sanitized_username,
1422 vuser->session_info->unix_info->unix_name,
1423 vuser->session_info->info->domain_name);
1428 /* Does this call need to be run as the connected user? */
1429 if (flags & AS_USER) {
1431 /* Does this call need a valid tree connection? */
1432 if (!conn) {
1434 * Amazingly, the error code depends on the command
1435 * (from Samba4).
1437 if (type == SMBntcreateX) {
1438 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1439 } else {
1440 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1442 return NULL;
1445 if (!change_to_user(conn,session_tag)) {
1446 DEBUG(0, ("Error: Could not change to user. Removing "
1447 "deferred open, mid=%llu.\n",
1448 (unsigned long long)req->mid));
1449 reply_force_doserror(req, ERRSRV, ERRbaduid);
1450 return conn;
1453 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1455 /* Does it need write permission? */
1456 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1457 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1458 return conn;
1461 /* IPC services are limited */
1462 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1463 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1464 return conn;
1466 } else {
1467 /* This call needs to be run as root */
1468 change_to_root_user();
1471 /* load service specific parameters */
1472 if (conn) {
1473 if (req->encrypted) {
1474 conn->encrypted_tid = true;
1475 /* encrypted required from now on. */
1476 conn->encrypt_level = Required;
1477 } else if (ENCRYPTION_REQUIRED(conn)) {
1478 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1479 exit_server_cleanly("encryption required "
1480 "on connection");
1481 return conn;
1485 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1486 (flags & (AS_USER|DO_CHDIR)
1487 ?True:False))) {
1488 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1489 return conn;
1491 conn->num_smb_operations++;
1494 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1495 talloc_tos());
1496 if (raddr == NULL) {
1497 reply_nterror(req, NT_STATUS_NO_MEMORY);
1498 return conn;
1501 /* does this protocol need to be run as guest? */
1502 if ((flags & AS_GUEST)
1503 && (!change_to_guest() ||
1504 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1505 sconn->remote_hostname,
1506 raddr))) {
1507 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1508 return conn;
1511 smb_messages[type].fn(req);
1512 return req->conn;
1515 /****************************************************************************
1516 Construct a reply to the incoming packet.
1517 ****************************************************************************/
1519 static void construct_reply(struct smbd_server_connection *sconn,
1520 char *inbuf, int size, size_t unread_bytes,
1521 uint32_t seqnum, bool encrypted,
1522 struct smb_perfcount_data *deferred_pcd)
1524 connection_struct *conn;
1525 struct smb_request *req;
1527 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1528 smb_panic("could not allocate smb_request");
1531 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1532 encrypted, seqnum)) {
1533 exit_server_cleanly("Invalid SMB request");
1536 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1538 /* we popped this message off the queue - keep original perf data */
1539 if (deferred_pcd)
1540 req->pcd = *deferred_pcd;
1541 else {
1542 SMB_PERFCOUNT_START(&req->pcd);
1543 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1544 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1547 conn = switch_message(req->cmd, req, size);
1549 if (req->unread_bytes) {
1550 /* writeX failed. drain socket. */
1551 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1552 req->unread_bytes) {
1553 smb_panic("failed to drain pending bytes");
1555 req->unread_bytes = 0;
1558 if (req->done) {
1559 TALLOC_FREE(req);
1560 return;
1563 if (req->outbuf == NULL) {
1564 return;
1567 if (CVAL(req->outbuf,0) == 0) {
1568 show_msg((char *)req->outbuf);
1571 if (!srv_send_smb(req->sconn,
1572 (char *)req->outbuf,
1573 true, req->seqnum+1,
1574 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1575 &req->pcd)) {
1576 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1579 TALLOC_FREE(req);
1581 return;
1584 /****************************************************************************
1585 Process an smb from the client
1586 ****************************************************************************/
1587 static void process_smb(struct smbd_server_connection *sconn,
1588 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1589 uint32_t seqnum, bool encrypted,
1590 struct smb_perfcount_data *deferred_pcd)
1592 int msg_type = CVAL(inbuf,0);
1594 DO_PROFILE_INC(smb_count);
1596 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1597 smb_len(inbuf) ) );
1598 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1599 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1601 if (msg_type != NBSSmessage) {
1603 * NetBIOS session request, keepalive, etc.
1605 reply_special(sconn, (char *)inbuf, nread);
1606 goto done;
1609 if (sconn->using_smb2) {
1610 /* At this point we're not really using smb2,
1611 * we make the decision here.. */
1612 if (smbd_is_smb2_header(inbuf, nread)) {
1613 smbd_smb2_first_negprot(sconn, inbuf, nread);
1614 return;
1615 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1616 && CVAL(inbuf, smb_com) != 0x72) {
1617 /* This is a non-negprot SMB1 packet.
1618 Disable SMB2 from now on. */
1619 sconn->using_smb2 = false;
1623 show_msg((char *)inbuf);
1625 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1626 encrypted, deferred_pcd);
1627 sconn->trans_num++;
1629 done:
1630 sconn->num_requests++;
1632 /* The timeout_processing function isn't run nearly
1633 often enough to implement 'max log size' without
1634 overrunning the size of the file by many megabytes.
1635 This is especially true if we are running at debug
1636 level 10. Checking every 50 SMBs is a nice
1637 tradeoff of performance vs log file size overrun. */
1639 if ((sconn->num_requests % 50) == 0 &&
1640 need_to_check_log_size()) {
1641 change_to_root_user();
1642 check_log_size();
1646 /****************************************************************************
1647 Return a string containing the function name of a SMB command.
1648 ****************************************************************************/
1650 const char *smb_fn_name(int type)
1652 const char *unknown_name = "SMBunknown";
1654 if (smb_messages[type].name == NULL)
1655 return(unknown_name);
1657 return(smb_messages[type].name);
1660 /****************************************************************************
1661 Helper functions for contruct_reply.
1662 ****************************************************************************/
1664 void add_to_common_flags2(uint32 v)
1666 common_flags2 |= v;
1669 void remove_from_common_flags2(uint32 v)
1671 common_flags2 &= ~v;
1674 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1675 char *outbuf)
1677 srv_set_message(outbuf,0,0,false);
1679 SCVAL(outbuf, smb_com, req->cmd);
1680 SIVAL(outbuf,smb_rcls,0);
1681 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1682 SSVAL(outbuf,smb_flg2,
1683 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1684 common_flags2);
1685 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1687 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1688 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1689 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1690 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1693 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1695 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1699 * How many bytes have we already accumulated up to the current wct field
1700 * offset?
1703 size_t req_wct_ofs(struct smb_request *req)
1705 size_t buf_size;
1707 if (req->chain_outbuf == NULL) {
1708 return smb_wct - 4;
1710 buf_size = talloc_get_size(req->chain_outbuf);
1711 if ((buf_size % 4) != 0) {
1712 buf_size += (4 - (buf_size % 4));
1714 return buf_size - 4;
1718 * Hack around reply_nterror & friends not being aware of chained requests,
1719 * generating illegal (i.e. wct==0) chain replies.
1722 static void fixup_chain_error_packet(struct smb_request *req)
1724 uint8_t *outbuf = req->outbuf;
1725 req->outbuf = NULL;
1726 reply_outbuf(req, 2, 0);
1727 memcpy(req->outbuf, outbuf, smb_wct);
1728 TALLOC_FREE(outbuf);
1729 SCVAL(req->outbuf, smb_vwv0, 0xff);
1733 * @brief Find the smb_cmd offset of the last command pushed
1734 * @param[in] buf The buffer we're building up
1735 * @retval Where can we put our next andx cmd?
1737 * While chaining requests, the "next" request we're looking at needs to put
1738 * its SMB_Command before the data the previous request already built up added
1739 * to the chain. Find the offset to the place where we have to put our cmd.
1742 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1744 uint8_t cmd;
1745 size_t ofs;
1747 cmd = CVAL(buf, smb_com);
1749 SMB_ASSERT(is_andx_req(cmd));
1751 ofs = smb_vwv0;
1753 while (CVAL(buf, ofs) != 0xff) {
1755 if (!is_andx_req(CVAL(buf, ofs))) {
1756 return false;
1760 * ofs is from start of smb header, so add the 4 length
1761 * bytes. The next cmd is right after the wct field.
1763 ofs = SVAL(buf, ofs+2) + 4 + 1;
1765 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1768 *pofs = ofs;
1769 return true;
1773 * @brief Do the smb chaining at a buffer level
1774 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1775 * @param[in] smb_command The command that we want to issue
1776 * @param[in] wct How many words?
1777 * @param[in] vwv The words, already in network order
1778 * @param[in] bytes_alignment How shall we align "bytes"?
1779 * @param[in] num_bytes How many bytes?
1780 * @param[in] bytes The data the request ships
1782 * smb_splice_chain() adds the vwv and bytes to the request already present in
1783 * *poutbuf.
1786 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1787 uint8_t wct, const uint16_t *vwv,
1788 size_t bytes_alignment,
1789 uint32_t num_bytes, const uint8_t *bytes)
1791 uint8_t *outbuf;
1792 size_t old_size, new_size;
1793 size_t ofs;
1794 size_t chain_padding = 0;
1795 size_t bytes_padding = 0;
1796 bool first_request;
1798 old_size = talloc_get_size(*poutbuf);
1801 * old_size == smb_wct means we're pushing the first request in for
1802 * libsmb/
1805 first_request = (old_size == smb_wct);
1807 if (!first_request && ((old_size % 4) != 0)) {
1809 * Align the wct field of subsequent requests to a 4-byte
1810 * boundary
1812 chain_padding = 4 - (old_size % 4);
1816 * After the old request comes the new wct field (1 byte), the vwv's
1817 * and the num_bytes field. After at we might need to align the bytes
1818 * given to us to "bytes_alignment", increasing the num_bytes value.
1821 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1823 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1824 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1827 new_size += bytes_padding + num_bytes;
1829 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1830 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1831 (unsigned)new_size));
1832 return false;
1835 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1836 if (outbuf == NULL) {
1837 DEBUG(0, ("talloc failed\n"));
1838 return false;
1840 *poutbuf = outbuf;
1842 if (first_request) {
1843 SCVAL(outbuf, smb_com, smb_command);
1844 } else {
1845 size_t andx_cmd_ofs;
1847 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1848 DEBUG(1, ("invalid command chain\n"));
1849 *poutbuf = talloc_realloc(
1850 NULL, *poutbuf, uint8_t, old_size);
1851 return false;
1854 if (chain_padding != 0) {
1855 memset(outbuf + old_size, 0, chain_padding);
1856 old_size += chain_padding;
1859 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1860 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1863 ofs = old_size;
1866 * Push the chained request:
1868 * wct field
1871 SCVAL(outbuf, ofs, wct);
1872 ofs += 1;
1875 * vwv array
1878 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1879 ofs += sizeof(uint16_t) * wct;
1882 * bcc (byte count)
1885 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1886 ofs += sizeof(uint16_t);
1889 * padding
1892 if (bytes_padding != 0) {
1893 memset(outbuf + ofs, 0, bytes_padding);
1894 ofs += bytes_padding;
1898 * The bytes field
1901 memcpy(outbuf + ofs, bytes, num_bytes);
1903 return true;
1906 /****************************************************************************
1907 Construct a chained reply and add it to the already made reply
1908 ****************************************************************************/
1910 void chain_reply(struct smb_request *req)
1912 size_t smblen = smb_len(req->inbuf);
1913 size_t already_used, length_needed;
1914 uint8_t chain_cmd;
1915 uint32_t chain_offset; /* uint32_t to avoid overflow */
1917 uint8_t wct;
1918 const uint16_t *vwv;
1919 uint16_t buflen;
1920 const uint8_t *buf;
1922 if (IVAL(req->outbuf, smb_rcls) != 0) {
1923 fixup_chain_error_packet(req);
1927 * Any of the AndX requests and replies have at least a wct of
1928 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1929 * beginning of the SMB header to the next wct field.
1931 * None of the AndX requests put anything valuable in vwv[0] and [1],
1932 * so we can overwrite it here to form the chain.
1935 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1936 if (req->chain_outbuf == NULL) {
1937 req->chain_outbuf = talloc_realloc(
1938 req, req->outbuf, uint8_t,
1939 smb_len(req->outbuf) + 4);
1940 if (req->chain_outbuf == NULL) {
1941 smb_panic("talloc failed");
1944 req->outbuf = NULL;
1945 goto error;
1949 * Here we assume that this is the end of the chain. For that we need
1950 * to set "next command" to 0xff and the offset to 0. If we later find
1951 * more commands in the chain, this will be overwritten again.
1954 SCVAL(req->outbuf, smb_vwv0, 0xff);
1955 SCVAL(req->outbuf, smb_vwv0+1, 0);
1956 SSVAL(req->outbuf, smb_vwv1, 0);
1958 if (req->chain_outbuf == NULL) {
1960 * In req->chain_outbuf we collect all the replies. Start the
1961 * chain by copying in the first reply.
1963 * We do the realloc because later on we depend on
1964 * talloc_get_size to determine the length of
1965 * chain_outbuf. The reply_xxx routines might have
1966 * over-allocated (reply_pipe_read_and_X used to be such an
1967 * example).
1969 req->chain_outbuf = talloc_realloc(
1970 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1971 if (req->chain_outbuf == NULL) {
1972 smb_panic("talloc failed");
1974 req->outbuf = NULL;
1975 } else {
1977 * Update smb headers where subsequent chained commands
1978 * may have updated them.
1980 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1981 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1983 if (!smb_splice_chain(&req->chain_outbuf,
1984 CVAL(req->outbuf, smb_com),
1985 CVAL(req->outbuf, smb_wct),
1986 (uint16_t *)(req->outbuf + smb_vwv),
1987 0, smb_buflen(req->outbuf),
1988 (uint8_t *)smb_buf(req->outbuf))) {
1989 goto error;
1991 TALLOC_FREE(req->outbuf);
1995 * We use the old request's vwv field to grab the next chained command
1996 * and offset into the chained fields.
1999 chain_cmd = CVAL(req->vwv+0, 0);
2000 chain_offset = SVAL(req->vwv+1, 0);
2002 if (chain_cmd == 0xff) {
2004 * End of chain, no more requests from the client. So ship the
2005 * replies.
2007 smb_setlen((char *)(req->chain_outbuf),
2008 talloc_get_size(req->chain_outbuf) - 4);
2010 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2011 true, req->seqnum+1,
2012 IS_CONN_ENCRYPTED(req->conn)
2013 ||req->encrypted,
2014 &req->pcd)) {
2015 exit_server_cleanly("chain_reply: srv_send_smb "
2016 "failed.");
2018 TALLOC_FREE(req->chain_outbuf);
2019 req->done = true;
2020 return;
2023 /* add a new perfcounter for this element of chain */
2024 SMB_PERFCOUNT_ADD(&req->pcd);
2025 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2026 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2029 * Check if the client tries to fool us. The chain offset
2030 * needs to point beyond the current request in the chain, it
2031 * needs to strictly grow. Otherwise we might be tricked into
2032 * an endless loop always processing the same request over and
2033 * over again. We used to assume that vwv and the byte buffer
2034 * array in a chain are always attached, but OS/2 the
2035 * Write&X/Read&X chain puts the Read&X vwv array right behind
2036 * the Write&X vwv chain. The Write&X bcc array is put behind
2037 * the Read&X vwv array. So now we check whether the chain
2038 * offset points strictly behind the previous vwv
2039 * array. req->buf points right after the vwv array of the
2040 * previous request. See
2041 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2042 * information.
2045 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2046 if (chain_offset <= already_used) {
2047 goto error;
2051 * Next check: Make sure the chain offset does not point beyond the
2052 * overall smb request length.
2055 length_needed = chain_offset+1; /* wct */
2056 if (length_needed > smblen) {
2057 goto error;
2061 * Now comes the pointer magic. Goal here is to set up req->vwv and
2062 * req->buf correctly again to be able to call the subsequent
2063 * switch_message(). The chain offset (the former vwv[1]) points at
2064 * the new wct field.
2067 wct = CVAL(smb_base(req->inbuf), chain_offset);
2070 * Next consistency check: Make the new vwv array fits in the overall
2071 * smb request.
2074 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2075 if (length_needed > smblen) {
2076 goto error;
2078 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2081 * Now grab the new byte buffer....
2084 buflen = SVAL(vwv+wct, 0);
2087 * .. and check that it fits.
2090 length_needed += buflen;
2091 if (length_needed > smblen) {
2092 goto error;
2094 buf = (const uint8_t *)(vwv+wct+1);
2096 req->cmd = chain_cmd;
2097 req->wct = wct;
2098 req->vwv = discard_const_p(uint16_t, vwv);
2099 req->buflen = buflen;
2100 req->buf = buf;
2102 switch_message(chain_cmd, req, smblen);
2104 if (req->outbuf == NULL) {
2106 * This happens if the chained command has suspended itself or
2107 * if it has called srv_send_smb() itself.
2109 return;
2113 * We end up here if the chained command was not itself chained or
2114 * suspended, but for example a close() command. We now need to splice
2115 * the chained commands' outbuf into the already built up chain_outbuf
2116 * and ship the result.
2118 goto done;
2120 error:
2122 * We end up here if there's any error in the chain syntax. Report a
2123 * DOS error, just like Windows does.
2125 reply_force_doserror(req, ERRSRV, ERRerror);
2126 fixup_chain_error_packet(req);
2128 done:
2130 * This scary statement intends to set the
2131 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2132 * to the value req->outbuf carries
2134 SSVAL(req->chain_outbuf, smb_flg2,
2135 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2136 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2139 * Transfer the error codes from the subrequest to the main one
2141 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2142 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2144 if (!smb_splice_chain(&req->chain_outbuf,
2145 CVAL(req->outbuf, smb_com),
2146 CVAL(req->outbuf, smb_wct),
2147 (uint16_t *)(req->outbuf + smb_vwv),
2148 0, smb_buflen(req->outbuf),
2149 (uint8_t *)smb_buf(req->outbuf))) {
2150 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2152 TALLOC_FREE(req->outbuf);
2154 smb_setlen((char *)(req->chain_outbuf),
2155 talloc_get_size(req->chain_outbuf) - 4);
2157 show_msg((char *)(req->chain_outbuf));
2159 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2160 true, req->seqnum+1,
2161 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2162 &req->pcd)) {
2163 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2165 TALLOC_FREE(req->chain_outbuf);
2166 req->done = true;
2169 /****************************************************************************
2170 Check if services need reloading.
2171 ****************************************************************************/
2173 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2176 if (last_smb_conf_reload_time == 0) {
2177 last_smb_conf_reload_time = t;
2180 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2181 reload_services(sconn->msg_ctx, sconn->sock, True);
2182 last_smb_conf_reload_time = t;
2186 static bool fd_is_readable(int fd)
2188 int ret, revents;
2190 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2192 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2196 static void smbd_server_connection_write_handler(
2197 struct smbd_server_connection *sconn)
2199 /* TODO: make write nonblocking */
2202 static void smbd_server_connection_read_handler(
2203 struct smbd_server_connection *sconn, int fd)
2205 uint8_t *inbuf = NULL;
2206 size_t inbuf_len = 0;
2207 size_t unread_bytes = 0;
2208 bool encrypted = false;
2209 TALLOC_CTX *mem_ctx = talloc_tos();
2210 NTSTATUS status;
2211 uint32_t seqnum;
2213 bool from_client = (sconn->sock == fd);
2215 if (from_client) {
2216 smbd_lock_socket(sconn);
2218 if (lp_async_smb_echo_handler()) {
2220 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2222 * This is the super-ugly hack to
2223 * prefer the packets forwarded by the
2224 * echo handler over the ones by the
2225 * client directly
2227 fd = sconn->smb1.echo_handler.trusted_fd;
2228 } else if (!fd_is_readable(fd)) {
2229 DEBUG(10,("the echo listener was faster\n"));
2230 smbd_unlock_socket(sconn);
2231 return;
2235 /* TODO: make this completely nonblocking */
2236 status = receive_smb_talloc(mem_ctx, sconn, fd,
2237 (char **)(void *)&inbuf,
2238 0, /* timeout */
2239 &unread_bytes,
2240 &encrypted,
2241 &inbuf_len, &seqnum,
2242 false /* trusted channel */);
2243 smbd_unlock_socket(sconn);
2244 } else {
2245 /* TODO: make this completely nonblocking */
2246 status = receive_smb_talloc(mem_ctx, sconn, fd,
2247 (char **)(void *)&inbuf,
2248 0, /* timeout */
2249 &unread_bytes,
2250 &encrypted,
2251 &inbuf_len, &seqnum,
2252 true /* trusted channel */);
2255 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2256 goto process;
2258 if (NT_STATUS_IS_ERR(status)) {
2259 exit_server_cleanly("failed to receive smb request");
2261 if (!NT_STATUS_IS_OK(status)) {
2262 return;
2265 process:
2266 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2267 seqnum, encrypted, NULL);
2270 static void smbd_server_connection_handler(struct event_context *ev,
2271 struct fd_event *fde,
2272 uint16_t flags,
2273 void *private_data)
2275 struct smbd_server_connection *conn = talloc_get_type(private_data,
2276 struct smbd_server_connection);
2278 if (flags & EVENT_FD_WRITE) {
2279 smbd_server_connection_write_handler(conn);
2280 return;
2282 if (flags & EVENT_FD_READ) {
2283 smbd_server_connection_read_handler(conn, conn->sock);
2284 return;
2288 static void smbd_server_echo_handler(struct event_context *ev,
2289 struct fd_event *fde,
2290 uint16_t flags,
2291 void *private_data)
2293 struct smbd_server_connection *conn = talloc_get_type(private_data,
2294 struct smbd_server_connection);
2296 if (flags & EVENT_FD_WRITE) {
2297 smbd_server_connection_write_handler(conn);
2298 return;
2300 if (flags & EVENT_FD_READ) {
2301 smbd_server_connection_read_handler(
2302 conn, conn->smb1.echo_handler.trusted_fd);
2303 return;
2307 #ifdef CLUSTER_SUPPORT
2308 /****************************************************************************
2309 received when we should release a specific IP
2310 ****************************************************************************/
2311 static void release_ip(const char *ip, void *priv)
2313 const char *addr = (const char *)priv;
2314 const char *p = addr;
2316 if (strncmp("::ffff:", addr, 7) == 0) {
2317 p = addr + 7;
2320 DEBUG(10, ("Got release IP message for %s, "
2321 "our address is %s\n", ip, p));
2323 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2324 /* we can't afford to do a clean exit - that involves
2325 database writes, which would potentially mean we
2326 are still running after the failover has finished -
2327 we have to get rid of this process ID straight
2328 away */
2329 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2330 ip));
2331 /* note we must exit with non-zero status so the unclean handler gets
2332 called in the parent, so that the brl database is tickled */
2333 _exit(1);
2337 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2338 struct sockaddr_storage *client)
2340 socklen_t length;
2341 length = sizeof(*server);
2342 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2343 return -1;
2345 length = sizeof(*client);
2346 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2347 return -1;
2349 return 0;
2351 #endif
2354 * Send keepalive packets to our client
2356 static bool keepalive_fn(const struct timeval *now, void *private_data)
2358 struct smbd_server_connection *sconn = smbd_server_conn;
2359 bool ret;
2361 if (sconn->using_smb2) {
2362 /* Don't do keepalives on an SMB2 connection. */
2363 return false;
2366 smbd_lock_socket(smbd_server_conn);
2367 ret = send_keepalive(sconn->sock);
2368 smbd_unlock_socket(smbd_server_conn);
2370 if (!ret) {
2371 char addr[INET6_ADDRSTRLEN];
2373 * Try and give an error message saying what
2374 * client failed.
2376 DEBUG(0, ("send_keepalive failed for client %s. "
2377 "Error %s - exiting\n",
2378 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2379 strerror(errno)));
2380 return False;
2382 return True;
2386 * Do the recurring check if we're idle
2388 static bool deadtime_fn(const struct timeval *now, void *private_data)
2390 struct smbd_server_connection *sconn =
2391 (struct smbd_server_connection *)private_data;
2393 if ((conn_num_open(sconn) == 0)
2394 || (conn_idle_all(sconn, now->tv_sec))) {
2395 DEBUG( 2, ( "Closing idle connection\n" ) );
2396 messaging_send(sconn->msg_ctx,
2397 messaging_server_id(sconn->msg_ctx),
2398 MSG_SHUTDOWN, &data_blob_null);
2399 return False;
2402 return True;
2406 * Do the recurring log file and smb.conf reload checks.
2409 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2411 struct smbd_server_connection *sconn = talloc_get_type_abort(
2412 private_data, struct smbd_server_connection);
2414 DEBUG(5, ("housekeeping\n"));
2416 change_to_root_user();
2418 /* update printer queue caches if necessary */
2419 update_monitored_printq_cache(sconn->msg_ctx);
2421 /* check if we need to reload services */
2422 check_reload(sconn, time_mono(NULL));
2424 /* Change machine password if neccessary. */
2425 attempt_machine_password_change();
2428 * Force a log file check.
2430 force_check_log_size();
2431 check_log_size();
2432 return true;
2436 * Read an smb packet in the echo handler child, giving the parent
2437 * smbd one second to react once the socket becomes readable.
2440 struct smbd_echo_read_state {
2441 struct tevent_context *ev;
2442 struct smbd_server_connection *sconn;
2444 char *buf;
2445 size_t buflen;
2446 uint32_t seqnum;
2449 static void smbd_echo_read_readable(struct tevent_req *subreq);
2450 static void smbd_echo_read_waited(struct tevent_req *subreq);
2452 static struct tevent_req *smbd_echo_read_send(
2453 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2454 struct smbd_server_connection *sconn)
2456 struct tevent_req *req, *subreq;
2457 struct smbd_echo_read_state *state;
2459 req = tevent_req_create(mem_ctx, &state,
2460 struct smbd_echo_read_state);
2461 if (req == NULL) {
2462 return NULL;
2464 state->ev = ev;
2465 state->sconn = sconn;
2467 subreq = wait_for_read_send(state, ev, sconn->sock);
2468 if (tevent_req_nomem(subreq, req)) {
2469 return tevent_req_post(req, ev);
2471 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2472 return req;
2475 static void smbd_echo_read_readable(struct tevent_req *subreq)
2477 struct tevent_req *req = tevent_req_callback_data(
2478 subreq, struct tevent_req);
2479 struct smbd_echo_read_state *state = tevent_req_data(
2480 req, struct smbd_echo_read_state);
2481 bool ok;
2482 int err;
2484 ok = wait_for_read_recv(subreq, &err);
2485 TALLOC_FREE(subreq);
2486 if (!ok) {
2487 tevent_req_nterror(req, map_nt_error_from_unix(err));
2488 return;
2492 * Give the parent smbd one second to step in
2495 subreq = tevent_wakeup_send(
2496 state, state->ev, timeval_current_ofs(1, 0));
2497 if (tevent_req_nomem(subreq, req)) {
2498 return;
2500 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2503 static void smbd_echo_read_waited(struct tevent_req *subreq)
2505 struct tevent_req *req = tevent_req_callback_data(
2506 subreq, struct tevent_req);
2507 struct smbd_echo_read_state *state = tevent_req_data(
2508 req, struct smbd_echo_read_state);
2509 struct smbd_server_connection *sconn = state->sconn;
2510 bool ok;
2511 NTSTATUS status;
2512 size_t unread = 0;
2513 bool encrypted;
2515 ok = tevent_wakeup_recv(subreq);
2516 TALLOC_FREE(subreq);
2517 if (!ok) {
2518 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2519 return;
2522 ok = smbd_lock_socket_internal(sconn);
2523 if (!ok) {
2524 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2525 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2526 return;
2529 if (!fd_is_readable(sconn->sock)) {
2530 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2531 (int)sys_getpid()));
2533 ok = smbd_unlock_socket_internal(sconn);
2534 if (!ok) {
2535 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2536 DEBUG(1, ("%s: failed to unlock socket\n",
2537 __location__));
2538 return;
2541 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2542 if (tevent_req_nomem(subreq, req)) {
2543 return;
2545 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2546 return;
2549 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2550 0 /* timeout */,
2551 &unread,
2552 &encrypted,
2553 &state->buflen,
2554 &state->seqnum,
2555 false /* trusted_channel*/);
2557 if (tevent_req_nterror(req, status)) {
2558 tevent_req_nterror(req, status);
2559 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2560 (int)sys_getpid(), nt_errstr(status)));
2561 return;
2564 ok = smbd_unlock_socket_internal(sconn);
2565 if (!ok) {
2566 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2567 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2568 return;
2570 tevent_req_done(req);
2573 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2574 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2576 struct smbd_echo_read_state *state = tevent_req_data(
2577 req, struct smbd_echo_read_state);
2578 NTSTATUS status;
2580 if (tevent_req_is_nterror(req, &status)) {
2581 return status;
2583 *pbuf = talloc_move(mem_ctx, &state->buf);
2584 *pbuflen = state->buflen;
2585 *pseqnum = state->seqnum;
2586 return NT_STATUS_OK;
2589 struct smbd_echo_state {
2590 struct tevent_context *ev;
2591 struct iovec *pending;
2592 struct smbd_server_connection *sconn;
2593 int parent_pipe;
2595 struct tevent_fd *parent_fde;
2597 struct tevent_req *write_req;
2600 static void smbd_echo_writer_done(struct tevent_req *req);
2602 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2604 int num_pending;
2606 if (state->write_req != NULL) {
2607 return;
2610 num_pending = talloc_array_length(state->pending);
2611 if (num_pending == 0) {
2612 return;
2615 state->write_req = writev_send(state, state->ev, NULL,
2616 state->parent_pipe, false,
2617 state->pending, num_pending);
2618 if (state->write_req == NULL) {
2619 DEBUG(1, ("writev_send failed\n"));
2620 exit(1);
2623 talloc_steal(state->write_req, state->pending);
2624 state->pending = NULL;
2626 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2627 state);
2630 static void smbd_echo_writer_done(struct tevent_req *req)
2632 struct smbd_echo_state *state = tevent_req_callback_data(
2633 req, struct smbd_echo_state);
2634 ssize_t written;
2635 int err;
2637 written = writev_recv(req, &err);
2638 TALLOC_FREE(req);
2639 state->write_req = NULL;
2640 if (written == -1) {
2641 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2642 exit(1);
2644 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2645 smbd_echo_activate_writer(state);
2648 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2649 uint32_t seqnum)
2651 struct smb_request req;
2652 uint16_t num_replies;
2653 size_t out_len;
2654 char *outbuf;
2655 bool ok;
2657 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2658 DEBUG(10, ("Got netbios keepalive\n"));
2660 * Just swallow it
2662 return true;
2665 if (inbuf_len < smb_size) {
2666 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2667 return false;
2669 if (!valid_smb_header(smbd_server_conn, inbuf)) {
2670 DEBUG(10, ("Got invalid SMB header\n"));
2671 return false;
2674 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2675 seqnum)) {
2676 return false;
2678 req.inbuf = inbuf;
2680 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2681 smb_messages[req.cmd].name
2682 ? smb_messages[req.cmd].name : "unknown"));
2684 if (req.cmd != SMBecho) {
2685 return false;
2687 if (req.wct < 1) {
2688 return false;
2691 num_replies = SVAL(req.vwv+0, 0);
2692 if (num_replies != 1) {
2693 /* Not a Windows "Hey, you're still there?" request */
2694 return false;
2697 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2698 1, req.buflen)) {
2699 DEBUG(10, ("create_outbuf failed\n"));
2700 return false;
2702 req.outbuf = (uint8_t *)outbuf;
2704 SSVAL(req.outbuf, smb_vwv0, num_replies);
2706 if (req.buflen > 0) {
2707 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2710 out_len = smb_len(req.outbuf) + 4;
2712 ok = srv_send_smb(req.sconn,
2713 (char *)outbuf,
2714 true, seqnum+1,
2715 false, &req.pcd);
2716 TALLOC_FREE(outbuf);
2717 if (!ok) {
2718 exit(1);
2721 return true;
2724 static void smbd_echo_exit(struct tevent_context *ev,
2725 struct tevent_fd *fde, uint16_t flags,
2726 void *private_data)
2728 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2729 exit(0);
2732 static void smbd_echo_got_packet(struct tevent_req *req);
2734 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2735 int parent_pipe)
2737 struct smbd_echo_state *state;
2738 struct tevent_req *read_req;
2740 state = talloc_zero(sconn, struct smbd_echo_state);
2741 if (state == NULL) {
2742 DEBUG(1, ("talloc failed\n"));
2743 return;
2745 state->sconn = sconn;
2746 state->parent_pipe = parent_pipe;
2747 state->ev = s3_tevent_context_init(state);
2748 if (state->ev == NULL) {
2749 DEBUG(1, ("tevent_context_init failed\n"));
2750 TALLOC_FREE(state);
2751 return;
2753 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2754 TEVENT_FD_READ, smbd_echo_exit,
2755 state);
2756 if (state->parent_fde == NULL) {
2757 DEBUG(1, ("tevent_add_fd failed\n"));
2758 TALLOC_FREE(state);
2759 return;
2762 read_req = smbd_echo_read_send(state, state->ev, sconn);
2763 if (read_req == NULL) {
2764 DEBUG(1, ("smbd_echo_read_send failed\n"));
2765 TALLOC_FREE(state);
2766 return;
2768 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2770 while (true) {
2771 if (tevent_loop_once(state->ev) == -1) {
2772 DEBUG(1, ("tevent_loop_once failed: %s\n",
2773 strerror(errno)));
2774 break;
2777 TALLOC_FREE(state);
2780 static void smbd_echo_got_packet(struct tevent_req *req)
2782 struct smbd_echo_state *state = tevent_req_callback_data(
2783 req, struct smbd_echo_state);
2784 NTSTATUS status;
2785 char *buf = NULL;
2786 size_t buflen = 0;
2787 uint32_t seqnum = 0;
2788 bool reply;
2790 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2791 TALLOC_FREE(req);
2792 if (!NT_STATUS_IS_OK(status)) {
2793 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2794 nt_errstr(status)));
2795 exit(1);
2798 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2799 if (!reply) {
2800 size_t num_pending;
2801 struct iovec *tmp;
2802 struct iovec *iov;
2804 num_pending = talloc_array_length(state->pending);
2805 tmp = talloc_realloc(state, state->pending, struct iovec,
2806 num_pending+1);
2807 if (tmp == NULL) {
2808 DEBUG(1, ("talloc_realloc failed\n"));
2809 exit(1);
2811 state->pending = tmp;
2813 if (buflen >= smb_size) {
2815 * place the seqnum in the packet so that the main process
2816 * can reply with signing
2818 SIVAL(buf, smb_ss_field, seqnum);
2819 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2822 iov = &state->pending[num_pending];
2823 iov->iov_base = buf;
2824 iov->iov_len = buflen;
2826 DEBUG(10,("echo_handler[%d]: forward to main\n",
2827 (int)sys_getpid()));
2828 smbd_echo_activate_writer(state);
2831 req = smbd_echo_read_send(state, state->ev, state->sconn);
2832 if (req == NULL) {
2833 DEBUG(1, ("smbd_echo_read_send failed\n"));
2834 exit(1);
2836 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2841 * Handle SMBecho requests in a forked child process
2843 bool fork_echo_handler(struct smbd_server_connection *sconn)
2845 int listener_pipe[2];
2846 int res;
2847 pid_t child;
2849 res = pipe(listener_pipe);
2850 if (res == -1) {
2851 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2852 return false;
2854 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2855 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2856 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2857 goto fail;
2860 child = sys_fork();
2861 if (child == 0) {
2862 NTSTATUS status;
2864 close(listener_pipe[0]);
2865 set_blocking(listener_pipe[1], false);
2867 status = reinit_after_fork(sconn->msg_ctx,
2868 server_event_context(),
2869 procid_self(), false);
2870 if (!NT_STATUS_IS_OK(status)) {
2871 DEBUG(1, ("reinit_after_fork failed: %s\n",
2872 nt_errstr(status)));
2873 exit(1);
2875 smbd_echo_loop(sconn, listener_pipe[1]);
2876 exit(0);
2878 close(listener_pipe[1]);
2879 listener_pipe[1] = -1;
2880 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2882 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2885 * Without smb signing this is the same as the normal smbd
2886 * listener. This needs to change once signing comes in.
2888 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2889 sconn,
2890 sconn->smb1.echo_handler.trusted_fd,
2891 EVENT_FD_READ,
2892 smbd_server_echo_handler,
2893 sconn);
2894 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2895 DEBUG(1, ("event_add_fd failed\n"));
2896 goto fail;
2899 return true;
2901 fail:
2902 if (listener_pipe[0] != -1) {
2903 close(listener_pipe[0]);
2905 if (listener_pipe[1] != -1) {
2906 close(listener_pipe[1]);
2908 sconn->smb1.echo_handler.trusted_fd = -1;
2909 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2910 close(sconn->smb1.echo_handler.socket_lock_fd);
2912 sconn->smb1.echo_handler.trusted_fd = -1;
2913 sconn->smb1.echo_handler.socket_lock_fd = -1;
2914 return false;
2917 #if CLUSTER_SUPPORT
2919 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2920 struct sockaddr_storage *srv,
2921 struct sockaddr_storage *clnt)
2923 struct ctdbd_connection *cconn;
2924 char tmp_addr[INET6_ADDRSTRLEN];
2925 char *addr;
2927 cconn = messaging_ctdbd_connection();
2928 if (cconn == NULL) {
2929 return NT_STATUS_NO_MEMORY;
2932 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2933 addr = talloc_strdup(cconn, tmp_addr);
2934 if (addr == NULL) {
2935 return NT_STATUS_NO_MEMORY;
2937 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2940 #endif
2942 /****************************************************************************
2943 Process commands from the client
2944 ****************************************************************************/
2946 void smbd_process(struct tevent_context *ev_ctx,
2947 struct smbd_server_connection *sconn)
2949 TALLOC_CTX *frame = talloc_stackframe();
2950 struct sockaddr_storage ss;
2951 struct sockaddr *sa = NULL;
2952 socklen_t sa_socklen;
2953 struct tsocket_address *local_address = NULL;
2954 struct tsocket_address *remote_address = NULL;
2955 const char *remaddr = NULL;
2956 char *rhost;
2957 int ret;
2959 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2961 * We're not making the decision here,
2962 * we're just allowing the client
2963 * to decide between SMB1 and SMB2
2964 * with the first negprot
2965 * packet.
2967 sconn->using_smb2 = true;
2970 /* Ensure child is set to blocking mode */
2971 set_blocking(sconn->sock,True);
2973 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2974 set_socket_options(sconn->sock, lp_socket_options());
2976 sa = (struct sockaddr *)(void *)&ss;
2977 sa_socklen = sizeof(ss);
2978 ret = getpeername(sconn->sock, sa, &sa_socklen);
2979 if (ret != 0) {
2980 int level = (errno == ENOTCONN)?2:0;
2981 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2982 exit_server_cleanly("getpeername() failed.\n");
2984 ret = tsocket_address_bsd_from_sockaddr(sconn,
2985 sa, sa_socklen,
2986 &remote_address);
2987 if (ret != 0) {
2988 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2989 __location__, strerror(errno)));
2990 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2993 sa = (struct sockaddr *)(void *)&ss;
2994 sa_socklen = sizeof(ss);
2995 ret = getsockname(sconn->sock, sa, &sa_socklen);
2996 if (ret != 0) {
2997 int level = (errno == ENOTCONN)?2:0;
2998 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2999 exit_server_cleanly("getsockname() failed.\n");
3001 ret = tsocket_address_bsd_from_sockaddr(sconn,
3002 sa, sa_socklen,
3003 &local_address);
3004 if (ret != 0) {
3005 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3006 __location__, strerror(errno)));
3007 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3010 sconn->local_address = local_address;
3011 sconn->remote_address = remote_address;
3013 if (tsocket_address_is_inet(remote_address, "ip")) {
3014 remaddr = tsocket_address_inet_addr_string(
3015 sconn->remote_address,
3016 talloc_tos());
3017 if (remaddr == NULL) {
3018 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3019 __location__, strerror(errno)));
3020 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3022 } else {
3023 remaddr = "0.0.0.0";
3026 /* this is needed so that we get decent entries
3027 in smbstatus for port 445 connects */
3028 set_remote_machine_name(remaddr, false);
3029 reload_services(sconn->msg_ctx, sconn->sock, true);
3032 * Before the first packet, check the global hosts allow/ hosts deny
3033 * parameters before doing any parsing of packets passed to us by the
3034 * client. This prevents attacks on our parsing code from hosts not in
3035 * the hosts allow list.
3038 ret = get_remote_hostname(remote_address,
3039 &rhost,
3040 talloc_tos());
3041 if (ret < 0) {
3042 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3043 __location__, strerror(errno)));
3044 exit_server_cleanly("get_remote_hostname failed.\n");
3046 if (strequal(rhost, "UNKNOWN")) {
3047 rhost = talloc_strdup(talloc_tos(), remaddr);
3049 sconn->remote_hostname = talloc_move(sconn, &rhost);
3051 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3052 sconn->remote_hostname,
3053 remaddr)) {
3055 * send a negative session response "not listening on calling
3056 * name"
3058 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3059 DEBUG( 1, ("Connection denied from %s to %s\n",
3060 tsocket_address_string(remote_address, talloc_tos()),
3061 tsocket_address_string(local_address, talloc_tos())));
3062 (void)srv_send_smb(sconn,(char *)buf, false,
3063 0, false, NULL);
3064 exit_server_cleanly("connection denied");
3067 DEBUG(10, ("Connection allowed from %s to %s\n",
3068 tsocket_address_string(remote_address, talloc_tos()),
3069 tsocket_address_string(local_address, talloc_tos())));
3071 init_modules();
3073 smb_perfcount_init();
3075 if (!init_account_policy()) {
3076 exit_server("Could not open account policy tdb.\n");
3079 if (*lp_rootdir()) {
3080 if (chroot(lp_rootdir()) != 0) {
3081 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3082 exit_server("Failed to chroot()");
3084 if (chdir("/") == -1) {
3085 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3086 exit_server("Failed to chroot()");
3088 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3091 if (!srv_init_signing(sconn)) {
3092 exit_server("Failed to init smb_signing");
3095 /* Setup oplocks */
3096 if (!init_oplocks(sconn->msg_ctx))
3097 exit_server("Failed to init oplocks");
3099 /* register our message handlers */
3100 messaging_register(sconn->msg_ctx, NULL,
3101 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3102 messaging_register(sconn->msg_ctx, NULL,
3103 MSG_SMB_CLOSE_FILE, msg_close_file);
3106 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3107 * MSGs to all child processes
3109 messaging_deregister(sconn->msg_ctx,
3110 MSG_DEBUG, NULL);
3111 messaging_register(sconn->msg_ctx, NULL,
3112 MSG_DEBUG, debug_message);
3114 if ((lp_keepalive() != 0)
3115 && !(event_add_idle(ev_ctx, NULL,
3116 timeval_set(lp_keepalive(), 0),
3117 "keepalive", keepalive_fn,
3118 NULL))) {
3119 DEBUG(0, ("Could not add keepalive event\n"));
3120 exit(1);
3123 if (!(event_add_idle(ev_ctx, NULL,
3124 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3125 "deadtime", deadtime_fn, sconn))) {
3126 DEBUG(0, ("Could not add deadtime event\n"));
3127 exit(1);
3130 if (!(event_add_idle(ev_ctx, NULL,
3131 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3132 "housekeeping", housekeeping_fn, sconn))) {
3133 DEBUG(0, ("Could not add housekeeping event\n"));
3134 exit(1);
3137 #ifdef CLUSTER_SUPPORT
3139 if (lp_clustering()) {
3141 * We need to tell ctdb about our client's TCP
3142 * connection, so that for failover ctdbd can send
3143 * tickle acks, triggering a reconnection by the
3144 * client.
3147 struct sockaddr_storage srv, clnt;
3149 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3150 NTSTATUS status;
3151 status = smbd_register_ips(sconn, &srv, &clnt);
3152 if (!NT_STATUS_IS_OK(status)) {
3153 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3154 nt_errstr(status)));
3156 } else
3158 DEBUG(0,("Unable to get tcp info for "
3159 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3160 strerror(errno)));
3164 #endif
3166 sconn->nbt.got_session = false;
3168 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3170 sconn->smb1.sessions.done_sesssetup = false;
3171 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3172 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3173 /* users from session setup */
3174 sconn->smb1.sessions.session_userlist = NULL;
3175 /* workgroup from session setup. */
3176 sconn->smb1.sessions.session_workgroup = NULL;
3177 /* this holds info on user ids that are already validated for this VC */
3178 sconn->smb1.sessions.validated_users = NULL;
3179 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3180 sconn->smb1.sessions.num_validated_vuids = 0;
3182 conn_init(sconn);
3183 if (!init_dptrs(sconn)) {
3184 exit_server("init_dptrs() failed");
3187 sconn->smb1.fde = event_add_fd(ev_ctx,
3188 sconn,
3189 sconn->sock,
3190 EVENT_FD_READ,
3191 smbd_server_connection_handler,
3192 sconn);
3193 if (!sconn->smb1.fde) {
3194 exit_server("failed to create smbd_server_connection fde");
3197 TALLOC_FREE(frame);
3199 while (True) {
3200 NTSTATUS status;
3202 frame = talloc_stackframe_pool(8192);
3204 errno = 0;
3206 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3207 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3208 !NT_STATUS_IS_OK(status)) {
3209 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3210 " exiting\n", nt_errstr(status)));
3211 break;
3214 TALLOC_FREE(frame);
3217 exit_server_cleanly(NULL);
3220 bool req_is_in_chain(struct smb_request *req)
3222 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3224 * We're right now handling a subsequent request, so we must
3225 * be in a chain
3227 return true;
3230 if (!is_andx_req(req->cmd)) {
3231 return false;
3234 if (req->wct < 2) {
3236 * Okay, an illegal request, but definitely not chained :-)
3238 return false;
3241 return (CVAL(req->vwv+0, 0) != 0xFF);