s3-wafbuild: Fix inotify detection (bug 8580)
[Samba/bjacke.git] / source3 / smbd / process.c
blob0ad554228b231e59fa7c5e242da2ba4ab3738de2
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(sconn, 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(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
460 ("receive_smb_raw_talloc failed for client %s "
461 "read error = %s.\n",
462 tsocket_address_string(sconn->remote_address,
463 talloc_tos()),
464 nt_errstr(status)) );
465 return status;
468 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
469 status = srv_decrypt_buffer(sconn, *buffer);
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
472 "incoming packet! Error %s\n",
473 nt_errstr(status) ));
474 return status;
476 *p_encrypted = true;
479 /* Check the incoming SMB signature. */
480 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
481 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
482 "incoming packet!\n"));
483 return NT_STATUS_INVALID_NETWORK_RESPONSE;
486 *p_len = len;
487 return NT_STATUS_OK;
491 * Initialize a struct smb_request from an inbuf
494 static bool init_smb_request(struct smb_request *req,
495 struct smbd_server_connection *sconn,
496 const uint8 *inbuf,
497 size_t unread_bytes, bool encrypted,
498 uint32_t seqnum)
500 size_t req_size = smb_len(inbuf) + 4;
501 /* Ensure we have at least smb_size bytes. */
502 if (req_size < smb_size) {
503 DEBUG(0,("init_smb_request: invalid request size %u\n",
504 (unsigned int)req_size ));
505 return false;
507 req->cmd = CVAL(inbuf, smb_com);
508 req->flags2 = SVAL(inbuf, smb_flg2);
509 req->smbpid = SVAL(inbuf, smb_pid);
510 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
511 req->seqnum = seqnum;
512 req->vuid = SVAL(inbuf, smb_uid);
513 req->tid = SVAL(inbuf, smb_tid);
514 req->wct = CVAL(inbuf, smb_wct);
515 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
516 req->buflen = smb_buflen(inbuf);
517 req->buf = (const uint8_t *)smb_buf_const(inbuf);
518 req->unread_bytes = unread_bytes;
519 req->encrypted = encrypted;
520 req->sconn = sconn;
521 req->conn = conn_find(sconn,req->tid);
522 req->chain_fsp = NULL;
523 req->chain_outbuf = NULL;
524 req->done = false;
525 req->smb2req = NULL;
526 smb_init_perfcount_data(&req->pcd);
528 /* Ensure we have at least wct words and 2 bytes of bcc. */
529 if (smb_size + req->wct*2 > req_size) {
530 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
531 (unsigned int)req->wct,
532 (unsigned int)req_size));
533 return false;
535 /* Ensure bcc is correct. */
536 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
537 DEBUG(0,("init_smb_request: invalid bcc number %u "
538 "(wct = %u, size %u)\n",
539 (unsigned int)req->buflen,
540 (unsigned int)req->wct,
541 (unsigned int)req_size));
542 return false;
545 req->outbuf = NULL;
546 return true;
549 static void process_smb(struct smbd_server_connection *conn,
550 uint8_t *inbuf, size_t nread, size_t unread_bytes,
551 uint32_t seqnum, bool encrypted,
552 struct smb_perfcount_data *deferred_pcd);
554 static void smbd_deferred_open_timer(struct event_context *ev,
555 struct timed_event *te,
556 struct timeval _tval,
557 void *private_data)
559 struct pending_message_list *msg = talloc_get_type(private_data,
560 struct pending_message_list);
561 TALLOC_CTX *mem_ctx = talloc_tos();
562 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
563 uint8_t *inbuf;
565 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
566 msg->buf.length);
567 if (inbuf == NULL) {
568 exit_server("smbd_deferred_open_timer: talloc failed\n");
569 return;
572 /* We leave this message on the queue so the open code can
573 know this is a retry. */
574 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
575 (unsigned long long)mid ));
577 /* Mark the message as processed so this is not
578 * re-processed in error. */
579 msg->processed = true;
581 process_smb(smbd_server_conn, inbuf,
582 msg->buf.length, 0,
583 msg->seqnum, msg->encrypted, &msg->pcd);
585 /* If it's still there and was processed, remove it. */
586 msg = get_deferred_open_message_smb(smbd_server_conn, mid);
587 if (msg && msg->processed) {
588 remove_deferred_open_message_smb(smbd_server_conn, mid);
592 /****************************************************************************
593 Function to push a message onto the tail of a linked list of smb messages ready
594 for processing.
595 ****************************************************************************/
597 static bool push_queued_message(struct smb_request *req,
598 struct timeval request_time,
599 struct timeval end_time,
600 char *private_data, size_t private_len)
602 int msg_len = smb_len(req->inbuf) + 4;
603 struct pending_message_list *msg;
605 msg = talloc_zero(NULL, struct pending_message_list);
607 if(msg == NULL) {
608 DEBUG(0,("push_message: malloc fail (1)\n"));
609 return False;
612 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
613 if(msg->buf.data == NULL) {
614 DEBUG(0,("push_message: malloc fail (2)\n"));
615 TALLOC_FREE(msg);
616 return False;
619 msg->request_time = request_time;
620 msg->seqnum = req->seqnum;
621 msg->encrypted = req->encrypted;
622 msg->processed = false;
623 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
625 if (private_data) {
626 msg->private_data = data_blob_talloc(msg, private_data,
627 private_len);
628 if (msg->private_data.data == NULL) {
629 DEBUG(0,("push_message: malloc fail (3)\n"));
630 TALLOC_FREE(msg);
631 return False;
635 msg->te = event_add_timed(server_event_context(),
636 msg,
637 end_time,
638 smbd_deferred_open_timer,
639 msg);
640 if (!msg->te) {
641 DEBUG(0,("push_message: event_add_timed failed\n"));
642 TALLOC_FREE(msg);
643 return false;
646 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
647 struct pending_message_list *);
649 DEBUG(10,("push_message: pushed message length %u on "
650 "deferred_open_queue\n", (unsigned int)msg_len));
652 return True;
655 /****************************************************************************
656 Function to delete a sharing violation open message by mid.
657 ****************************************************************************/
659 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
660 uint64_t mid)
662 struct pending_message_list *pml;
664 if (sconn->using_smb2) {
665 remove_deferred_open_message_smb2(sconn, mid);
666 return;
669 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
670 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
671 DEBUG(10,("remove_deferred_open_message_smb: "
672 "deleting mid %llu len %u\n",
673 (unsigned long long)mid,
674 (unsigned int)pml->buf.length ));
675 DLIST_REMOVE(sconn->deferred_open_queue, pml);
676 TALLOC_FREE(pml);
677 return;
682 /****************************************************************************
683 Move a sharing violation open retry message to the front of the list and
684 schedule it for immediate processing.
685 ****************************************************************************/
687 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
688 uint64_t mid)
690 struct pending_message_list *pml;
691 int i = 0;
693 if (sconn->using_smb2) {
694 schedule_deferred_open_message_smb2(sconn, mid);
695 return;
698 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
699 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
701 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
702 "msg_mid = %llu\n",
703 i++,
704 (unsigned long long)msg_mid ));
706 if (mid == msg_mid) {
707 struct timed_event *te;
709 if (pml->processed) {
710 /* A processed message should not be
711 * rescheduled. */
712 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
713 "message mid %llu was already processed\n",
714 (unsigned long long)msg_mid ));
715 continue;
718 DEBUG(10,("schedule_deferred_open_message_smb: "
719 "scheduling mid %llu\n",
720 (unsigned long long)mid ));
722 te = event_add_timed(server_event_context(),
723 pml,
724 timeval_zero(),
725 smbd_deferred_open_timer,
726 pml);
727 if (!te) {
728 DEBUG(10,("schedule_deferred_open_message_smb: "
729 "event_add_timed() failed, "
730 "skipping mid %llu\n",
731 (unsigned long long)msg_mid ));
734 TALLOC_FREE(pml->te);
735 pml->te = te;
736 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
737 return;
741 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
742 "find message mid %llu\n",
743 (unsigned long long)mid ));
746 /****************************************************************************
747 Return true if this mid is on the deferred queue and was not yet processed.
748 ****************************************************************************/
750 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
752 struct pending_message_list *pml;
754 if (sconn->using_smb2) {
755 return open_was_deferred_smb2(sconn, mid);
758 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
759 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
760 return True;
763 return False;
766 /****************************************************************************
767 Return the message queued by this mid.
768 ****************************************************************************/
770 static struct pending_message_list *get_deferred_open_message_smb(
771 struct smbd_server_connection *sconn, uint64_t mid)
773 struct pending_message_list *pml;
775 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
776 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
777 return pml;
780 return NULL;
783 /****************************************************************************
784 Get the state data queued by this mid.
785 ****************************************************************************/
787 bool get_deferred_open_message_state(struct smb_request *smbreq,
788 struct timeval *p_request_time,
789 void **pp_state)
791 struct pending_message_list *pml;
793 if (smbd_server_conn->using_smb2) {
794 return get_deferred_open_message_state_smb2(smbreq->smb2req,
795 p_request_time,
796 pp_state);
799 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
800 if (!pml) {
801 return false;
803 if (p_request_time) {
804 *p_request_time = pml->request_time;
806 if (pp_state) {
807 *pp_state = (void *)pml->private_data.data;
809 return true;
812 /****************************************************************************
813 Function to push a deferred open smb message onto a linked list of local smb
814 messages ready for processing.
815 ****************************************************************************/
817 bool push_deferred_open_message_smb(struct smb_request *req,
818 struct timeval request_time,
819 struct timeval timeout,
820 struct file_id id,
821 char *private_data, size_t priv_len)
823 struct timeval end_time;
825 if (req->smb2req) {
826 return push_deferred_open_message_smb2(req->smb2req,
827 request_time,
828 timeout,
830 private_data,
831 priv_len);
834 if (req->unread_bytes) {
835 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
836 "unread_bytes = %u\n",
837 (unsigned int)req->unread_bytes ));
838 smb_panic("push_deferred_open_message_smb: "
839 "logic error unread_bytes != 0" );
842 end_time = timeval_sum(&request_time, &timeout);
844 DEBUG(10,("push_deferred_open_message_smb: pushing message "
845 "len %u mid %llu timeout time [%u.%06u]\n",
846 (unsigned int) smb_len(req->inbuf)+4,
847 (unsigned long long)req->mid,
848 (unsigned int)end_time.tv_sec,
849 (unsigned int)end_time.tv_usec));
851 return push_queued_message(req, request_time, end_time,
852 private_data, priv_len);
855 static void smbd_sig_term_handler(struct tevent_context *ev,
856 struct tevent_signal *se,
857 int signum,
858 int count,
859 void *siginfo,
860 void *private_data)
862 exit_server_cleanly("termination signal");
865 void smbd_setup_sig_term_handler(void)
867 struct tevent_signal *se;
869 se = tevent_add_signal(server_event_context(),
870 server_event_context(),
871 SIGTERM, 0,
872 smbd_sig_term_handler,
873 NULL);
874 if (!se) {
875 exit_server("failed to setup SIGTERM handler");
879 static void smbd_sig_hup_handler(struct tevent_context *ev,
880 struct tevent_signal *se,
881 int signum,
882 int count,
883 void *siginfo,
884 void *private_data)
886 struct messaging_context *msg_ctx = talloc_get_type_abort(
887 private_data, struct messaging_context);
888 change_to_root_user();
889 DEBUG(1,("Reloading services after SIGHUP\n"));
890 reload_services(msg_ctx, smbd_server_conn->sock, False);
891 if (am_parent) {
892 printing_subsystem_update(ev, msg_ctx, true);
896 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
897 struct messaging_context *msg_ctx)
899 struct tevent_signal *se;
901 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
902 msg_ctx);
903 if (!se) {
904 exit_server("failed to setup SIGHUP handler");
908 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
909 struct smbd_server_connection *conn)
911 int timeout;
912 int num_pfds = 0;
913 int ret;
914 bool retry;
916 timeout = SMBD_SELECT_TIMEOUT * 1000;
919 * Are there any timed events waiting ? If so, ensure we don't
920 * select for longer than it would take to wait for them.
923 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
925 /* Process a signal and timed events now... */
926 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
927 return NT_STATUS_RETRY;
931 int sav;
932 START_PROFILE(smbd_idle);
934 ret = sys_poll(conn->pfds, num_pfds, timeout);
935 sav = errno;
937 END_PROFILE(smbd_idle);
938 errno = sav;
941 if (ret == -1) {
942 if (errno == EINTR) {
943 return NT_STATUS_RETRY;
945 return map_nt_error_from_unix(errno);
948 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
949 if (retry) {
950 return NT_STATUS_RETRY;
953 /* Did we timeout ? */
954 if (ret == 0) {
955 return NT_STATUS_RETRY;
958 /* should not be reached */
959 return NT_STATUS_INTERNAL_ERROR;
963 * Only allow 5 outstanding trans requests. We're allocating memory, so
964 * prevent a DoS.
967 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
969 int count = 0;
970 for (; list != NULL; list = list->next) {
972 if (list->mid == mid) {
973 return NT_STATUS_INVALID_PARAMETER;
976 count += 1;
978 if (count > 5) {
979 return NT_STATUS_INSUFFICIENT_RESOURCES;
982 return NT_STATUS_OK;
986 These flags determine some of the permissions required to do an operation
988 Note that I don't set NEED_WRITE on some write operations because they
989 are used by some brain-dead clients when printing, and I don't want to
990 force write permissions on print services.
992 #define AS_USER (1<<0)
993 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
994 #define TIME_INIT (1<<2)
995 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
996 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
997 #define DO_CHDIR (1<<6)
1000 define a list of possible SMB messages and their corresponding
1001 functions. Any message that has a NULL function is unimplemented -
1002 please feel free to contribute implementations!
1004 static const struct smb_message_struct {
1005 const char *name;
1006 void (*fn)(struct smb_request *req);
1007 int flags;
1008 } smb_messages[256] = {
1010 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1011 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1012 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1013 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1014 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1015 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1016 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1017 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1018 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1019 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1020 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1021 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1022 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1023 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1024 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1025 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1026 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1027 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1028 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1029 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1030 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1031 /* 0x15 */ { NULL, NULL, 0 },
1032 /* 0x16 */ { NULL, NULL, 0 },
1033 /* 0x17 */ { NULL, NULL, 0 },
1034 /* 0x18 */ { NULL, NULL, 0 },
1035 /* 0x19 */ { NULL, NULL, 0 },
1036 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1037 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1038 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1039 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1040 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1041 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1042 /* 0x20 */ { "SMBwritec", NULL,0},
1043 /* 0x21 */ { NULL, NULL, 0 },
1044 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1045 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1046 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1047 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1048 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1049 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1050 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1051 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1052 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1053 /* 0x2b */ { "SMBecho",reply_echo,0},
1054 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1055 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1056 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1057 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1058 /* 0x30 */ { NULL, NULL, 0 },
1059 /* 0x31 */ { NULL, NULL, 0 },
1060 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1061 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1062 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1063 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1064 /* 0x36 */ { NULL, NULL, 0 },
1065 /* 0x37 */ { NULL, NULL, 0 },
1066 /* 0x38 */ { NULL, NULL, 0 },
1067 /* 0x39 */ { NULL, NULL, 0 },
1068 /* 0x3a */ { NULL, NULL, 0 },
1069 /* 0x3b */ { NULL, NULL, 0 },
1070 /* 0x3c */ { NULL, NULL, 0 },
1071 /* 0x3d */ { NULL, NULL, 0 },
1072 /* 0x3e */ { NULL, NULL, 0 },
1073 /* 0x3f */ { NULL, NULL, 0 },
1074 /* 0x40 */ { NULL, NULL, 0 },
1075 /* 0x41 */ { NULL, NULL, 0 },
1076 /* 0x42 */ { NULL, NULL, 0 },
1077 /* 0x43 */ { NULL, NULL, 0 },
1078 /* 0x44 */ { NULL, NULL, 0 },
1079 /* 0x45 */ { NULL, NULL, 0 },
1080 /* 0x46 */ { NULL, NULL, 0 },
1081 /* 0x47 */ { NULL, NULL, 0 },
1082 /* 0x48 */ { NULL, NULL, 0 },
1083 /* 0x49 */ { NULL, NULL, 0 },
1084 /* 0x4a */ { NULL, NULL, 0 },
1085 /* 0x4b */ { NULL, NULL, 0 },
1086 /* 0x4c */ { NULL, NULL, 0 },
1087 /* 0x4d */ { NULL, NULL, 0 },
1088 /* 0x4e */ { NULL, NULL, 0 },
1089 /* 0x4f */ { NULL, NULL, 0 },
1090 /* 0x50 */ { NULL, NULL, 0 },
1091 /* 0x51 */ { NULL, NULL, 0 },
1092 /* 0x52 */ { NULL, NULL, 0 },
1093 /* 0x53 */ { NULL, NULL, 0 },
1094 /* 0x54 */ { NULL, NULL, 0 },
1095 /* 0x55 */ { NULL, NULL, 0 },
1096 /* 0x56 */ { NULL, NULL, 0 },
1097 /* 0x57 */ { NULL, NULL, 0 },
1098 /* 0x58 */ { NULL, NULL, 0 },
1099 /* 0x59 */ { NULL, NULL, 0 },
1100 /* 0x5a */ { NULL, NULL, 0 },
1101 /* 0x5b */ { NULL, NULL, 0 },
1102 /* 0x5c */ { NULL, NULL, 0 },
1103 /* 0x5d */ { NULL, NULL, 0 },
1104 /* 0x5e */ { NULL, NULL, 0 },
1105 /* 0x5f */ { NULL, NULL, 0 },
1106 /* 0x60 */ { NULL, NULL, 0 },
1107 /* 0x61 */ { NULL, NULL, 0 },
1108 /* 0x62 */ { NULL, NULL, 0 },
1109 /* 0x63 */ { NULL, NULL, 0 },
1110 /* 0x64 */ { NULL, NULL, 0 },
1111 /* 0x65 */ { NULL, NULL, 0 },
1112 /* 0x66 */ { NULL, NULL, 0 },
1113 /* 0x67 */ { NULL, NULL, 0 },
1114 /* 0x68 */ { NULL, NULL, 0 },
1115 /* 0x69 */ { NULL, NULL, 0 },
1116 /* 0x6a */ { NULL, NULL, 0 },
1117 /* 0x6b */ { NULL, NULL, 0 },
1118 /* 0x6c */ { NULL, NULL, 0 },
1119 /* 0x6d */ { NULL, NULL, 0 },
1120 /* 0x6e */ { NULL, NULL, 0 },
1121 /* 0x6f */ { NULL, NULL, 0 },
1122 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1123 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1124 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1125 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1126 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1127 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1128 /* 0x76 */ { NULL, NULL, 0 },
1129 /* 0x77 */ { NULL, NULL, 0 },
1130 /* 0x78 */ { NULL, NULL, 0 },
1131 /* 0x79 */ { NULL, NULL, 0 },
1132 /* 0x7a */ { NULL, NULL, 0 },
1133 /* 0x7b */ { NULL, NULL, 0 },
1134 /* 0x7c */ { NULL, NULL, 0 },
1135 /* 0x7d */ { NULL, NULL, 0 },
1136 /* 0x7e */ { NULL, NULL, 0 },
1137 /* 0x7f */ { NULL, NULL, 0 },
1138 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1139 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1140 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1141 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1142 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1143 /* 0x85 */ { NULL, NULL, 0 },
1144 /* 0x86 */ { NULL, NULL, 0 },
1145 /* 0x87 */ { NULL, NULL, 0 },
1146 /* 0x88 */ { NULL, NULL, 0 },
1147 /* 0x89 */ { NULL, NULL, 0 },
1148 /* 0x8a */ { NULL, NULL, 0 },
1149 /* 0x8b */ { NULL, NULL, 0 },
1150 /* 0x8c */ { NULL, NULL, 0 },
1151 /* 0x8d */ { NULL, NULL, 0 },
1152 /* 0x8e */ { NULL, NULL, 0 },
1153 /* 0x8f */ { NULL, NULL, 0 },
1154 /* 0x90 */ { NULL, NULL, 0 },
1155 /* 0x91 */ { NULL, NULL, 0 },
1156 /* 0x92 */ { NULL, NULL, 0 },
1157 /* 0x93 */ { NULL, NULL, 0 },
1158 /* 0x94 */ { NULL, NULL, 0 },
1159 /* 0x95 */ { NULL, NULL, 0 },
1160 /* 0x96 */ { NULL, NULL, 0 },
1161 /* 0x97 */ { NULL, NULL, 0 },
1162 /* 0x98 */ { NULL, NULL, 0 },
1163 /* 0x99 */ { NULL, NULL, 0 },
1164 /* 0x9a */ { NULL, NULL, 0 },
1165 /* 0x9b */ { NULL, NULL, 0 },
1166 /* 0x9c */ { NULL, NULL, 0 },
1167 /* 0x9d */ { NULL, NULL, 0 },
1168 /* 0x9e */ { NULL, NULL, 0 },
1169 /* 0x9f */ { NULL, NULL, 0 },
1170 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1171 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1172 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1173 /* 0xa3 */ { NULL, NULL, 0 },
1174 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1175 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1176 /* 0xa6 */ { NULL, NULL, 0 },
1177 /* 0xa7 */ { NULL, NULL, 0 },
1178 /* 0xa8 */ { NULL, NULL, 0 },
1179 /* 0xa9 */ { NULL, NULL, 0 },
1180 /* 0xaa */ { NULL, NULL, 0 },
1181 /* 0xab */ { NULL, NULL, 0 },
1182 /* 0xac */ { NULL, NULL, 0 },
1183 /* 0xad */ { NULL, NULL, 0 },
1184 /* 0xae */ { NULL, NULL, 0 },
1185 /* 0xaf */ { NULL, NULL, 0 },
1186 /* 0xb0 */ { NULL, NULL, 0 },
1187 /* 0xb1 */ { NULL, NULL, 0 },
1188 /* 0xb2 */ { NULL, NULL, 0 },
1189 /* 0xb3 */ { NULL, NULL, 0 },
1190 /* 0xb4 */ { NULL, NULL, 0 },
1191 /* 0xb5 */ { NULL, NULL, 0 },
1192 /* 0xb6 */ { NULL, NULL, 0 },
1193 /* 0xb7 */ { NULL, NULL, 0 },
1194 /* 0xb8 */ { NULL, NULL, 0 },
1195 /* 0xb9 */ { NULL, NULL, 0 },
1196 /* 0xba */ { NULL, NULL, 0 },
1197 /* 0xbb */ { NULL, NULL, 0 },
1198 /* 0xbc */ { NULL, NULL, 0 },
1199 /* 0xbd */ { NULL, NULL, 0 },
1200 /* 0xbe */ { NULL, NULL, 0 },
1201 /* 0xbf */ { NULL, NULL, 0 },
1202 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1203 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1204 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1205 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1206 /* 0xc4 */ { NULL, NULL, 0 },
1207 /* 0xc5 */ { NULL, NULL, 0 },
1208 /* 0xc6 */ { NULL, NULL, 0 },
1209 /* 0xc7 */ { NULL, NULL, 0 },
1210 /* 0xc8 */ { NULL, NULL, 0 },
1211 /* 0xc9 */ { NULL, NULL, 0 },
1212 /* 0xca */ { NULL, NULL, 0 },
1213 /* 0xcb */ { NULL, NULL, 0 },
1214 /* 0xcc */ { NULL, NULL, 0 },
1215 /* 0xcd */ { NULL, NULL, 0 },
1216 /* 0xce */ { NULL, NULL, 0 },
1217 /* 0xcf */ { NULL, NULL, 0 },
1218 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1219 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1220 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1221 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1222 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1223 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1224 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1225 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1226 /* 0xd8 */ { NULL, NULL, 0 },
1227 /* 0xd9 */ { NULL, NULL, 0 },
1228 /* 0xda */ { NULL, NULL, 0 },
1229 /* 0xdb */ { NULL, NULL, 0 },
1230 /* 0xdc */ { NULL, NULL, 0 },
1231 /* 0xdd */ { NULL, NULL, 0 },
1232 /* 0xde */ { NULL, NULL, 0 },
1233 /* 0xdf */ { NULL, NULL, 0 },
1234 /* 0xe0 */ { NULL, NULL, 0 },
1235 /* 0xe1 */ { NULL, NULL, 0 },
1236 /* 0xe2 */ { NULL, NULL, 0 },
1237 /* 0xe3 */ { NULL, NULL, 0 },
1238 /* 0xe4 */ { NULL, NULL, 0 },
1239 /* 0xe5 */ { NULL, NULL, 0 },
1240 /* 0xe6 */ { NULL, NULL, 0 },
1241 /* 0xe7 */ { NULL, NULL, 0 },
1242 /* 0xe8 */ { NULL, NULL, 0 },
1243 /* 0xe9 */ { NULL, NULL, 0 },
1244 /* 0xea */ { NULL, NULL, 0 },
1245 /* 0xeb */ { NULL, NULL, 0 },
1246 /* 0xec */ { NULL, NULL, 0 },
1247 /* 0xed */ { NULL, NULL, 0 },
1248 /* 0xee */ { NULL, NULL, 0 },
1249 /* 0xef */ { NULL, NULL, 0 },
1250 /* 0xf0 */ { NULL, NULL, 0 },
1251 /* 0xf1 */ { NULL, NULL, 0 },
1252 /* 0xf2 */ { NULL, NULL, 0 },
1253 /* 0xf3 */ { NULL, NULL, 0 },
1254 /* 0xf4 */ { NULL, NULL, 0 },
1255 /* 0xf5 */ { NULL, NULL, 0 },
1256 /* 0xf6 */ { NULL, NULL, 0 },
1257 /* 0xf7 */ { NULL, NULL, 0 },
1258 /* 0xf8 */ { NULL, NULL, 0 },
1259 /* 0xf9 */ { NULL, NULL, 0 },
1260 /* 0xfa */ { NULL, NULL, 0 },
1261 /* 0xfb */ { NULL, NULL, 0 },
1262 /* 0xfc */ { NULL, NULL, 0 },
1263 /* 0xfd */ { NULL, NULL, 0 },
1264 /* 0xfe */ { NULL, NULL, 0 },
1265 /* 0xff */ { NULL, NULL, 0 }
1269 /*******************************************************************
1270 allocate and initialize a reply packet
1271 ********************************************************************/
1273 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1274 const char *inbuf, char **outbuf, uint8_t num_words,
1275 uint32_t num_bytes)
1278 * Protect against integer wrap
1280 if ((num_bytes > 0xffffff)
1281 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1282 char *msg;
1283 if (asprintf(&msg, "num_bytes too large: %u",
1284 (unsigned)num_bytes) == -1) {
1285 msg = discard_const_p(char, "num_bytes too large");
1287 smb_panic(msg);
1290 *outbuf = talloc_array(mem_ctx, char,
1291 smb_size + num_words*2 + num_bytes);
1292 if (*outbuf == NULL) {
1293 return false;
1296 construct_reply_common(req, inbuf, *outbuf);
1297 srv_set_message(*outbuf, num_words, num_bytes, false);
1299 * Zero out the word area, the caller has to take care of the bcc area
1300 * himself
1302 if (num_words != 0) {
1303 memset(*outbuf + smb_vwv0, 0, num_words*2);
1306 return true;
1309 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1311 char *outbuf;
1312 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1313 num_bytes)) {
1314 smb_panic("could not allocate output buffer\n");
1316 req->outbuf = (uint8_t *)outbuf;
1320 /*******************************************************************
1321 Dump a packet to a file.
1322 ********************************************************************/
1324 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1326 int fd, i;
1327 char *fname = NULL;
1328 if (DEBUGLEVEL < 50) {
1329 return;
1332 if (len < 4) len = smb_len(data)+4;
1333 for (i=1;i<100;i++) {
1334 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1335 type ? "req" : "resp") == -1) {
1336 return;
1338 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1339 if (fd != -1 || errno != EEXIST) break;
1341 if (fd != -1) {
1342 ssize_t ret = write(fd, data, len);
1343 if (ret != len)
1344 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1345 close(fd);
1346 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1348 SAFE_FREE(fname);
1351 /****************************************************************************
1352 Prepare everything for calling the actual request function, and potentially
1353 call the request function via the "new" interface.
1355 Return False if the "legacy" function needs to be called, everything is
1356 prepared.
1358 Return True if we're done.
1360 I know this API sucks, but it is the one with the least code change I could
1361 find.
1362 ****************************************************************************/
1364 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1366 int flags;
1367 uint16 session_tag;
1368 connection_struct *conn = NULL;
1369 struct smbd_server_connection *sconn = req->sconn;
1370 char *raddr;
1372 errno = 0;
1374 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1375 * so subtract 4 from it. */
1376 if (!valid_smb_header(sconn, req->inbuf)
1377 || (size < (smb_size - 4))) {
1378 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1379 smb_len(req->inbuf)));
1380 exit_server_cleanly("Non-SMB packet");
1383 if (smb_messages[type].fn == NULL) {
1384 DEBUG(0,("Unknown message type %d!\n",type));
1385 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1386 reply_unknown_new(req, type);
1387 return NULL;
1390 flags = smb_messages[type].flags;
1392 /* In share mode security we must ignore the vuid. */
1393 session_tag = (lp_security() == SEC_SHARE)
1394 ? UID_FIELD_INVALID : req->vuid;
1395 conn = req->conn;
1397 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1398 (int)sys_getpid(), (unsigned long)conn));
1400 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1402 /* Ensure this value is replaced in the incoming packet. */
1403 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1406 * Ensure the correct username is in current_user_info. This is a
1407 * really ugly bugfix for problems with multiple session_setup_and_X's
1408 * being done and allowing %U and %G substitutions to work correctly.
1409 * There is a reason this code is done here, don't move it unless you
1410 * know what you're doing... :-).
1411 * JRA.
1414 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1415 user_struct *vuser = NULL;
1417 sconn->smb1.sessions.last_session_tag = session_tag;
1418 if(session_tag != UID_FIELD_INVALID) {
1419 vuser = get_valid_user_struct(sconn, session_tag);
1420 if (vuser) {
1421 set_current_user_info(
1422 vuser->session_info->unix_info->sanitized_username,
1423 vuser->session_info->unix_info->unix_name,
1424 vuser->session_info->info->domain_name);
1429 /* Does this call need to be run as the connected user? */
1430 if (flags & AS_USER) {
1432 /* Does this call need a valid tree connection? */
1433 if (!conn) {
1435 * Amazingly, the error code depends on the command
1436 * (from Samba4).
1438 if (type == SMBntcreateX) {
1439 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1440 } else {
1441 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1443 return NULL;
1446 if (!change_to_user(conn,session_tag)) {
1447 DEBUG(0, ("Error: Could not change to user. Removing "
1448 "deferred open, mid=%llu.\n",
1449 (unsigned long long)req->mid));
1450 reply_force_doserror(req, ERRSRV, ERRbaduid);
1451 return conn;
1454 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1456 /* Does it need write permission? */
1457 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1458 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1459 return conn;
1462 /* IPC services are limited */
1463 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1464 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1465 return conn;
1467 } else {
1468 /* This call needs to be run as root */
1469 change_to_root_user();
1472 /* load service specific parameters */
1473 if (conn) {
1474 if (req->encrypted) {
1475 conn->encrypted_tid = true;
1476 /* encrypted required from now on. */
1477 conn->encrypt_level = Required;
1478 } else if (ENCRYPTION_REQUIRED(conn)) {
1479 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1480 exit_server_cleanly("encryption required "
1481 "on connection");
1482 return conn;
1486 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1487 (flags & (AS_USER|DO_CHDIR)
1488 ?True:False))) {
1489 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1490 return conn;
1492 conn->num_smb_operations++;
1495 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1496 talloc_tos());
1497 if (raddr == NULL) {
1498 reply_nterror(req, NT_STATUS_NO_MEMORY);
1499 return conn;
1502 /* does this protocol need to be run as guest? */
1503 if ((flags & AS_GUEST)
1504 && (!change_to_guest() ||
1505 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1506 sconn->remote_hostname,
1507 raddr))) {
1508 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 return conn;
1512 smb_messages[type].fn(req);
1513 return req->conn;
1516 /****************************************************************************
1517 Construct a reply to the incoming packet.
1518 ****************************************************************************/
1520 static void construct_reply(struct smbd_server_connection *sconn,
1521 char *inbuf, int size, size_t unread_bytes,
1522 uint32_t seqnum, bool encrypted,
1523 struct smb_perfcount_data *deferred_pcd)
1525 connection_struct *conn;
1526 struct smb_request *req;
1528 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1529 smb_panic("could not allocate smb_request");
1532 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1533 encrypted, seqnum)) {
1534 exit_server_cleanly("Invalid SMB request");
1537 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1539 /* we popped this message off the queue - keep original perf data */
1540 if (deferred_pcd)
1541 req->pcd = *deferred_pcd;
1542 else {
1543 SMB_PERFCOUNT_START(&req->pcd);
1544 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1545 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1548 conn = switch_message(req->cmd, req, size);
1550 if (req->unread_bytes) {
1551 /* writeX failed. drain socket. */
1552 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1553 req->unread_bytes) {
1554 smb_panic("failed to drain pending bytes");
1556 req->unread_bytes = 0;
1559 if (req->done) {
1560 TALLOC_FREE(req);
1561 return;
1564 if (req->outbuf == NULL) {
1565 return;
1568 if (CVAL(req->outbuf,0) == 0) {
1569 show_msg((char *)req->outbuf);
1572 if (!srv_send_smb(req->sconn,
1573 (char *)req->outbuf,
1574 true, req->seqnum+1,
1575 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1576 &req->pcd)) {
1577 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1580 TALLOC_FREE(req);
1582 return;
1585 /****************************************************************************
1586 Process an smb from the client
1587 ****************************************************************************/
1588 static void process_smb(struct smbd_server_connection *sconn,
1589 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1590 uint32_t seqnum, bool encrypted,
1591 struct smb_perfcount_data *deferred_pcd)
1593 int msg_type = CVAL(inbuf,0);
1595 DO_PROFILE_INC(smb_count);
1597 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1598 smb_len(inbuf) ) );
1599 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1600 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1602 if (msg_type != NBSSmessage) {
1604 * NetBIOS session request, keepalive, etc.
1606 reply_special(sconn, (char *)inbuf, nread);
1607 goto done;
1610 if (sconn->using_smb2) {
1611 /* At this point we're not really using smb2,
1612 * we make the decision here.. */
1613 if (smbd_is_smb2_header(inbuf, nread)) {
1614 smbd_smb2_first_negprot(sconn, inbuf, nread);
1615 return;
1616 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1617 && CVAL(inbuf, smb_com) != 0x72) {
1618 /* This is a non-negprot SMB1 packet.
1619 Disable SMB2 from now on. */
1620 sconn->using_smb2 = false;
1624 show_msg((char *)inbuf);
1626 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1627 encrypted, deferred_pcd);
1628 sconn->trans_num++;
1630 done:
1631 sconn->num_requests++;
1633 /* The timeout_processing function isn't run nearly
1634 often enough to implement 'max log size' without
1635 overrunning the size of the file by many megabytes.
1636 This is especially true if we are running at debug
1637 level 10. Checking every 50 SMBs is a nice
1638 tradeoff of performance vs log file size overrun. */
1640 if ((sconn->num_requests % 50) == 0 &&
1641 need_to_check_log_size()) {
1642 change_to_root_user();
1643 check_log_size();
1647 /****************************************************************************
1648 Return a string containing the function name of a SMB command.
1649 ****************************************************************************/
1651 const char *smb_fn_name(int type)
1653 const char *unknown_name = "SMBunknown";
1655 if (smb_messages[type].name == NULL)
1656 return(unknown_name);
1658 return(smb_messages[type].name);
1661 /****************************************************************************
1662 Helper functions for contruct_reply.
1663 ****************************************************************************/
1665 void add_to_common_flags2(uint32 v)
1667 common_flags2 |= v;
1670 void remove_from_common_flags2(uint32 v)
1672 common_flags2 &= ~v;
1675 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1676 char *outbuf)
1678 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1679 uint16_t out_flags2 = common_flags2;
1681 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1682 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1683 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1685 srv_set_message(outbuf,0,0,false);
1687 SCVAL(outbuf, smb_com, req->cmd);
1688 SIVAL(outbuf,smb_rcls,0);
1689 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1690 SSVAL(outbuf,smb_flg2, out_flags2);
1691 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1692 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1694 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1695 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1696 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1697 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1700 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1702 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1706 * How many bytes have we already accumulated up to the current wct field
1707 * offset?
1710 size_t req_wct_ofs(struct smb_request *req)
1712 size_t buf_size;
1714 if (req->chain_outbuf == NULL) {
1715 return smb_wct - 4;
1717 buf_size = talloc_get_size(req->chain_outbuf);
1718 if ((buf_size % 4) != 0) {
1719 buf_size += (4 - (buf_size % 4));
1721 return buf_size - 4;
1725 * Hack around reply_nterror & friends not being aware of chained requests,
1726 * generating illegal (i.e. wct==0) chain replies.
1729 static void fixup_chain_error_packet(struct smb_request *req)
1731 uint8_t *outbuf = req->outbuf;
1732 req->outbuf = NULL;
1733 reply_outbuf(req, 2, 0);
1734 memcpy(req->outbuf, outbuf, smb_wct);
1735 TALLOC_FREE(outbuf);
1736 SCVAL(req->outbuf, smb_vwv0, 0xff);
1740 * @brief Find the smb_cmd offset of the last command pushed
1741 * @param[in] buf The buffer we're building up
1742 * @retval Where can we put our next andx cmd?
1744 * While chaining requests, the "next" request we're looking at needs to put
1745 * its SMB_Command before the data the previous request already built up added
1746 * to the chain. Find the offset to the place where we have to put our cmd.
1749 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1751 uint8_t cmd;
1752 size_t ofs;
1754 cmd = CVAL(buf, smb_com);
1756 SMB_ASSERT(is_andx_req(cmd));
1758 ofs = smb_vwv0;
1760 while (CVAL(buf, ofs) != 0xff) {
1762 if (!is_andx_req(CVAL(buf, ofs))) {
1763 return false;
1767 * ofs is from start of smb header, so add the 4 length
1768 * bytes. The next cmd is right after the wct field.
1770 ofs = SVAL(buf, ofs+2) + 4 + 1;
1772 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1775 *pofs = ofs;
1776 return true;
1780 * @brief Do the smb chaining at a buffer level
1781 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1782 * @param[in] smb_command The command that we want to issue
1783 * @param[in] wct How many words?
1784 * @param[in] vwv The words, already in network order
1785 * @param[in] bytes_alignment How shall we align "bytes"?
1786 * @param[in] num_bytes How many bytes?
1787 * @param[in] bytes The data the request ships
1789 * smb_splice_chain() adds the vwv and bytes to the request already present in
1790 * *poutbuf.
1793 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1794 uint8_t wct, const uint16_t *vwv,
1795 size_t bytes_alignment,
1796 uint32_t num_bytes, const uint8_t *bytes)
1798 uint8_t *outbuf;
1799 size_t old_size, new_size;
1800 size_t ofs;
1801 size_t chain_padding = 0;
1802 size_t bytes_padding = 0;
1803 bool first_request;
1805 old_size = talloc_get_size(*poutbuf);
1808 * old_size == smb_wct means we're pushing the first request in for
1809 * libsmb/
1812 first_request = (old_size == smb_wct);
1814 if (!first_request && ((old_size % 4) != 0)) {
1816 * Align the wct field of subsequent requests to a 4-byte
1817 * boundary
1819 chain_padding = 4 - (old_size % 4);
1823 * After the old request comes the new wct field (1 byte), the vwv's
1824 * and the num_bytes field. After at we might need to align the bytes
1825 * given to us to "bytes_alignment", increasing the num_bytes value.
1828 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1830 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1831 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1834 new_size += bytes_padding + num_bytes;
1836 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1837 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1838 (unsigned)new_size));
1839 return false;
1842 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1843 if (outbuf == NULL) {
1844 DEBUG(0, ("talloc failed\n"));
1845 return false;
1847 *poutbuf = outbuf;
1849 if (first_request) {
1850 SCVAL(outbuf, smb_com, smb_command);
1851 } else {
1852 size_t andx_cmd_ofs;
1854 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1855 DEBUG(1, ("invalid command chain\n"));
1856 *poutbuf = talloc_realloc(
1857 NULL, *poutbuf, uint8_t, old_size);
1858 return false;
1861 if (chain_padding != 0) {
1862 memset(outbuf + old_size, 0, chain_padding);
1863 old_size += chain_padding;
1866 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1867 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1870 ofs = old_size;
1873 * Push the chained request:
1875 * wct field
1878 SCVAL(outbuf, ofs, wct);
1879 ofs += 1;
1882 * vwv array
1885 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1886 ofs += sizeof(uint16_t) * wct;
1889 * bcc (byte count)
1892 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1893 ofs += sizeof(uint16_t);
1896 * padding
1899 if (bytes_padding != 0) {
1900 memset(outbuf + ofs, 0, bytes_padding);
1901 ofs += bytes_padding;
1905 * The bytes field
1908 memcpy(outbuf + ofs, bytes, num_bytes);
1910 return true;
1913 /****************************************************************************
1914 Construct a chained reply and add it to the already made reply
1915 ****************************************************************************/
1917 void chain_reply(struct smb_request *req)
1919 size_t smblen = smb_len(req->inbuf);
1920 size_t already_used, length_needed;
1921 uint8_t chain_cmd;
1922 uint32_t chain_offset; /* uint32_t to avoid overflow */
1924 uint8_t wct;
1925 const uint16_t *vwv;
1926 uint16_t buflen;
1927 const uint8_t *buf;
1929 if (IVAL(req->outbuf, smb_rcls) != 0) {
1930 fixup_chain_error_packet(req);
1934 * Any of the AndX requests and replies have at least a wct of
1935 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1936 * beginning of the SMB header to the next wct field.
1938 * None of the AndX requests put anything valuable in vwv[0] and [1],
1939 * so we can overwrite it here to form the chain.
1942 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1943 if (req->chain_outbuf == NULL) {
1944 req->chain_outbuf = talloc_realloc(
1945 req, req->outbuf, uint8_t,
1946 smb_len(req->outbuf) + 4);
1947 if (req->chain_outbuf == NULL) {
1948 smb_panic("talloc failed");
1951 req->outbuf = NULL;
1952 goto error;
1956 * Here we assume that this is the end of the chain. For that we need
1957 * to set "next command" to 0xff and the offset to 0. If we later find
1958 * more commands in the chain, this will be overwritten again.
1961 SCVAL(req->outbuf, smb_vwv0, 0xff);
1962 SCVAL(req->outbuf, smb_vwv0+1, 0);
1963 SSVAL(req->outbuf, smb_vwv1, 0);
1965 if (req->chain_outbuf == NULL) {
1967 * In req->chain_outbuf we collect all the replies. Start the
1968 * chain by copying in the first reply.
1970 * We do the realloc because later on we depend on
1971 * talloc_get_size to determine the length of
1972 * chain_outbuf. The reply_xxx routines might have
1973 * over-allocated (reply_pipe_read_and_X used to be such an
1974 * example).
1976 req->chain_outbuf = talloc_realloc(
1977 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1978 if (req->chain_outbuf == NULL) {
1979 smb_panic("talloc failed");
1981 req->outbuf = NULL;
1982 } else {
1984 * Update smb headers where subsequent chained commands
1985 * may have updated them.
1987 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1988 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1990 if (!smb_splice_chain(&req->chain_outbuf,
1991 CVAL(req->outbuf, smb_com),
1992 CVAL(req->outbuf, smb_wct),
1993 (uint16_t *)(req->outbuf + smb_vwv),
1994 0, smb_buflen(req->outbuf),
1995 (uint8_t *)smb_buf(req->outbuf))) {
1996 goto error;
1998 TALLOC_FREE(req->outbuf);
2002 * We use the old request's vwv field to grab the next chained command
2003 * and offset into the chained fields.
2006 chain_cmd = CVAL(req->vwv+0, 0);
2007 chain_offset = SVAL(req->vwv+1, 0);
2009 if (chain_cmd == 0xff) {
2011 * End of chain, no more requests from the client. So ship the
2012 * replies.
2014 smb_setlen((char *)(req->chain_outbuf),
2015 talloc_get_size(req->chain_outbuf) - 4);
2017 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2018 true, req->seqnum+1,
2019 IS_CONN_ENCRYPTED(req->conn)
2020 ||req->encrypted,
2021 &req->pcd)) {
2022 exit_server_cleanly("chain_reply: srv_send_smb "
2023 "failed.");
2025 TALLOC_FREE(req->chain_outbuf);
2026 req->done = true;
2027 return;
2030 /* add a new perfcounter for this element of chain */
2031 SMB_PERFCOUNT_ADD(&req->pcd);
2032 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2033 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2036 * Check if the client tries to fool us. The chain offset
2037 * needs to point beyond the current request in the chain, it
2038 * needs to strictly grow. Otherwise we might be tricked into
2039 * an endless loop always processing the same request over and
2040 * over again. We used to assume that vwv and the byte buffer
2041 * array in a chain are always attached, but OS/2 the
2042 * Write&X/Read&X chain puts the Read&X vwv array right behind
2043 * the Write&X vwv chain. The Write&X bcc array is put behind
2044 * the Read&X vwv array. So now we check whether the chain
2045 * offset points strictly behind the previous vwv
2046 * array. req->buf points right after the vwv array of the
2047 * previous request. See
2048 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2049 * information.
2052 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2053 if (chain_offset <= already_used) {
2054 goto error;
2058 * Next check: Make sure the chain offset does not point beyond the
2059 * overall smb request length.
2062 length_needed = chain_offset+1; /* wct */
2063 if (length_needed > smblen) {
2064 goto error;
2068 * Now comes the pointer magic. Goal here is to set up req->vwv and
2069 * req->buf correctly again to be able to call the subsequent
2070 * switch_message(). The chain offset (the former vwv[1]) points at
2071 * the new wct field.
2074 wct = CVAL(smb_base(req->inbuf), chain_offset);
2077 * Next consistency check: Make the new vwv array fits in the overall
2078 * smb request.
2081 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2082 if (length_needed > smblen) {
2083 goto error;
2085 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2088 * Now grab the new byte buffer....
2091 buflen = SVAL(vwv+wct, 0);
2094 * .. and check that it fits.
2097 length_needed += buflen;
2098 if (length_needed > smblen) {
2099 goto error;
2101 buf = (const uint8_t *)(vwv+wct+1);
2103 req->cmd = chain_cmd;
2104 req->wct = wct;
2105 req->vwv = discard_const_p(uint16_t, vwv);
2106 req->buflen = buflen;
2107 req->buf = buf;
2109 switch_message(chain_cmd, req, smblen);
2111 if (req->outbuf == NULL) {
2113 * This happens if the chained command has suspended itself or
2114 * if it has called srv_send_smb() itself.
2116 return;
2120 * We end up here if the chained command was not itself chained or
2121 * suspended, but for example a close() command. We now need to splice
2122 * the chained commands' outbuf into the already built up chain_outbuf
2123 * and ship the result.
2125 goto done;
2127 error:
2129 * We end up here if there's any error in the chain syntax. Report a
2130 * DOS error, just like Windows does.
2132 reply_force_doserror(req, ERRSRV, ERRerror);
2133 fixup_chain_error_packet(req);
2135 done:
2137 * This scary statement intends to set the
2138 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2139 * to the value req->outbuf carries
2141 SSVAL(req->chain_outbuf, smb_flg2,
2142 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2143 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2146 * Transfer the error codes from the subrequest to the main one
2148 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2149 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2151 if (!smb_splice_chain(&req->chain_outbuf,
2152 CVAL(req->outbuf, smb_com),
2153 CVAL(req->outbuf, smb_wct),
2154 (uint16_t *)(req->outbuf + smb_vwv),
2155 0, smb_buflen(req->outbuf),
2156 (uint8_t *)smb_buf(req->outbuf))) {
2157 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2159 TALLOC_FREE(req->outbuf);
2161 smb_setlen((char *)(req->chain_outbuf),
2162 talloc_get_size(req->chain_outbuf) - 4);
2164 show_msg((char *)(req->chain_outbuf));
2166 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2167 true, req->seqnum+1,
2168 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2169 &req->pcd)) {
2170 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2172 TALLOC_FREE(req->chain_outbuf);
2173 req->done = true;
2176 /****************************************************************************
2177 Check if services need reloading.
2178 ****************************************************************************/
2180 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2183 if (last_smb_conf_reload_time == 0) {
2184 last_smb_conf_reload_time = t;
2187 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2188 reload_services(sconn->msg_ctx, sconn->sock, True);
2189 last_smb_conf_reload_time = t;
2193 static bool fd_is_readable(int fd)
2195 int ret, revents;
2197 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2199 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2203 static void smbd_server_connection_write_handler(
2204 struct smbd_server_connection *sconn)
2206 /* TODO: make write nonblocking */
2209 static void smbd_server_connection_read_handler(
2210 struct smbd_server_connection *sconn, int fd)
2212 uint8_t *inbuf = NULL;
2213 size_t inbuf_len = 0;
2214 size_t unread_bytes = 0;
2215 bool encrypted = false;
2216 TALLOC_CTX *mem_ctx = talloc_tos();
2217 NTSTATUS status;
2218 uint32_t seqnum;
2220 bool from_client = (sconn->sock == fd);
2222 if (from_client) {
2223 smbd_lock_socket(sconn);
2225 if (lp_async_smb_echo_handler()) {
2227 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2229 * This is the super-ugly hack to
2230 * prefer the packets forwarded by the
2231 * echo handler over the ones by the
2232 * client directly
2234 fd = sconn->smb1.echo_handler.trusted_fd;
2235 } else if (!fd_is_readable(fd)) {
2236 DEBUG(10,("the echo listener was faster\n"));
2237 smbd_unlock_socket(sconn);
2238 return;
2242 /* TODO: make this completely nonblocking */
2243 status = receive_smb_talloc(mem_ctx, sconn, fd,
2244 (char **)(void *)&inbuf,
2245 0, /* timeout */
2246 &unread_bytes,
2247 &encrypted,
2248 &inbuf_len, &seqnum,
2249 false /* trusted channel */);
2250 smbd_unlock_socket(sconn);
2251 } else {
2252 /* TODO: make this completely nonblocking */
2253 status = receive_smb_talloc(mem_ctx, sconn, fd,
2254 (char **)(void *)&inbuf,
2255 0, /* timeout */
2256 &unread_bytes,
2257 &encrypted,
2258 &inbuf_len, &seqnum,
2259 true /* trusted channel */);
2262 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2263 goto process;
2265 if (NT_STATUS_IS_ERR(status)) {
2266 exit_server_cleanly("failed to receive smb request");
2268 if (!NT_STATUS_IS_OK(status)) {
2269 return;
2272 process:
2273 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2274 seqnum, encrypted, NULL);
2277 static void smbd_server_connection_handler(struct event_context *ev,
2278 struct fd_event *fde,
2279 uint16_t flags,
2280 void *private_data)
2282 struct smbd_server_connection *conn = talloc_get_type(private_data,
2283 struct smbd_server_connection);
2285 if (flags & EVENT_FD_WRITE) {
2286 smbd_server_connection_write_handler(conn);
2287 return;
2289 if (flags & EVENT_FD_READ) {
2290 smbd_server_connection_read_handler(conn, conn->sock);
2291 return;
2295 static void smbd_server_echo_handler(struct event_context *ev,
2296 struct fd_event *fde,
2297 uint16_t flags,
2298 void *private_data)
2300 struct smbd_server_connection *conn = talloc_get_type(private_data,
2301 struct smbd_server_connection);
2303 if (flags & EVENT_FD_WRITE) {
2304 smbd_server_connection_write_handler(conn);
2305 return;
2307 if (flags & EVENT_FD_READ) {
2308 smbd_server_connection_read_handler(
2309 conn, conn->smb1.echo_handler.trusted_fd);
2310 return;
2314 #ifdef CLUSTER_SUPPORT
2315 /****************************************************************************
2316 received when we should release a specific IP
2317 ****************************************************************************/
2318 static void release_ip(const char *ip, void *priv)
2320 const char *addr = (const char *)priv;
2321 const char *p = addr;
2323 if (strncmp("::ffff:", addr, 7) == 0) {
2324 p = addr + 7;
2327 DEBUG(10, ("Got release IP message for %s, "
2328 "our address is %s\n", ip, p));
2330 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2331 /* we can't afford to do a clean exit - that involves
2332 database writes, which would potentially mean we
2333 are still running after the failover has finished -
2334 we have to get rid of this process ID straight
2335 away */
2336 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2337 ip));
2338 /* note we must exit with non-zero status so the unclean handler gets
2339 called in the parent, so that the brl database is tickled */
2340 _exit(1);
2344 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2345 struct sockaddr_storage *client)
2347 socklen_t length;
2348 length = sizeof(*server);
2349 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2350 return -1;
2352 length = sizeof(*client);
2353 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2354 return -1;
2356 return 0;
2358 #endif
2361 * Send keepalive packets to our client
2363 static bool keepalive_fn(const struct timeval *now, void *private_data)
2365 struct smbd_server_connection *sconn = talloc_get_type_abort(
2366 private_data, struct smbd_server_connection);
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;
2444 * Read an smb packet in the echo handler child, giving the parent
2445 * smbd one second to react once the socket becomes readable.
2448 struct smbd_echo_read_state {
2449 struct tevent_context *ev;
2450 struct smbd_server_connection *sconn;
2452 char *buf;
2453 size_t buflen;
2454 uint32_t seqnum;
2457 static void smbd_echo_read_readable(struct tevent_req *subreq);
2458 static void smbd_echo_read_waited(struct tevent_req *subreq);
2460 static struct tevent_req *smbd_echo_read_send(
2461 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2462 struct smbd_server_connection *sconn)
2464 struct tevent_req *req, *subreq;
2465 struct smbd_echo_read_state *state;
2467 req = tevent_req_create(mem_ctx, &state,
2468 struct smbd_echo_read_state);
2469 if (req == NULL) {
2470 return NULL;
2472 state->ev = ev;
2473 state->sconn = sconn;
2475 subreq = wait_for_read_send(state, ev, sconn->sock);
2476 if (tevent_req_nomem(subreq, req)) {
2477 return tevent_req_post(req, ev);
2479 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2480 return req;
2483 static void smbd_echo_read_readable(struct tevent_req *subreq)
2485 struct tevent_req *req = tevent_req_callback_data(
2486 subreq, struct tevent_req);
2487 struct smbd_echo_read_state *state = tevent_req_data(
2488 req, struct smbd_echo_read_state);
2489 bool ok;
2490 int err;
2492 ok = wait_for_read_recv(subreq, &err);
2493 TALLOC_FREE(subreq);
2494 if (!ok) {
2495 tevent_req_nterror(req, map_nt_error_from_unix(err));
2496 return;
2500 * Give the parent smbd one second to step in
2503 subreq = tevent_wakeup_send(
2504 state, state->ev, timeval_current_ofs(1, 0));
2505 if (tevent_req_nomem(subreq, req)) {
2506 return;
2508 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2511 static void smbd_echo_read_waited(struct tevent_req *subreq)
2513 struct tevent_req *req = tevent_req_callback_data(
2514 subreq, struct tevent_req);
2515 struct smbd_echo_read_state *state = tevent_req_data(
2516 req, struct smbd_echo_read_state);
2517 struct smbd_server_connection *sconn = state->sconn;
2518 bool ok;
2519 NTSTATUS status;
2520 size_t unread = 0;
2521 bool encrypted;
2523 ok = tevent_wakeup_recv(subreq);
2524 TALLOC_FREE(subreq);
2525 if (!ok) {
2526 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2527 return;
2530 ok = smbd_lock_socket_internal(sconn);
2531 if (!ok) {
2532 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2533 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2534 return;
2537 if (!fd_is_readable(sconn->sock)) {
2538 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2539 (int)sys_getpid()));
2541 ok = smbd_unlock_socket_internal(sconn);
2542 if (!ok) {
2543 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2544 DEBUG(1, ("%s: failed to unlock socket\n",
2545 __location__));
2546 return;
2549 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2550 if (tevent_req_nomem(subreq, req)) {
2551 return;
2553 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2554 return;
2557 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2558 0 /* timeout */,
2559 &unread,
2560 &encrypted,
2561 &state->buflen,
2562 &state->seqnum,
2563 false /* trusted_channel*/);
2565 if (tevent_req_nterror(req, status)) {
2566 tevent_req_nterror(req, status);
2567 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2568 (int)sys_getpid(), nt_errstr(status)));
2569 return;
2572 ok = smbd_unlock_socket_internal(sconn);
2573 if (!ok) {
2574 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2575 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2576 return;
2578 tevent_req_done(req);
2581 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2582 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2584 struct smbd_echo_read_state *state = tevent_req_data(
2585 req, struct smbd_echo_read_state);
2586 NTSTATUS status;
2588 if (tevent_req_is_nterror(req, &status)) {
2589 return status;
2591 *pbuf = talloc_move(mem_ctx, &state->buf);
2592 *pbuflen = state->buflen;
2593 *pseqnum = state->seqnum;
2594 return NT_STATUS_OK;
2597 struct smbd_echo_state {
2598 struct tevent_context *ev;
2599 struct iovec *pending;
2600 struct smbd_server_connection *sconn;
2601 int parent_pipe;
2603 struct tevent_fd *parent_fde;
2605 struct tevent_req *write_req;
2608 static void smbd_echo_writer_done(struct tevent_req *req);
2610 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2612 int num_pending;
2614 if (state->write_req != NULL) {
2615 return;
2618 num_pending = talloc_array_length(state->pending);
2619 if (num_pending == 0) {
2620 return;
2623 state->write_req = writev_send(state, state->ev, NULL,
2624 state->parent_pipe, false,
2625 state->pending, num_pending);
2626 if (state->write_req == NULL) {
2627 DEBUG(1, ("writev_send failed\n"));
2628 exit(1);
2631 talloc_steal(state->write_req, state->pending);
2632 state->pending = NULL;
2634 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2635 state);
2638 static void smbd_echo_writer_done(struct tevent_req *req)
2640 struct smbd_echo_state *state = tevent_req_callback_data(
2641 req, struct smbd_echo_state);
2642 ssize_t written;
2643 int err;
2645 written = writev_recv(req, &err);
2646 TALLOC_FREE(req);
2647 state->write_req = NULL;
2648 if (written == -1) {
2649 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2650 exit(1);
2652 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2653 smbd_echo_activate_writer(state);
2656 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2657 uint32_t seqnum)
2659 struct smb_request req;
2660 uint16_t num_replies;
2661 size_t out_len;
2662 char *outbuf;
2663 bool ok;
2665 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2666 DEBUG(10, ("Got netbios keepalive\n"));
2668 * Just swallow it
2670 return true;
2673 if (inbuf_len < smb_size) {
2674 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2675 return false;
2677 if (!valid_smb_header(smbd_server_conn, inbuf)) {
2678 DEBUG(10, ("Got invalid SMB header\n"));
2679 return false;
2682 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2683 seqnum)) {
2684 return false;
2686 req.inbuf = inbuf;
2688 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2689 smb_messages[req.cmd].name
2690 ? smb_messages[req.cmd].name : "unknown"));
2692 if (req.cmd != SMBecho) {
2693 return false;
2695 if (req.wct < 1) {
2696 return false;
2699 num_replies = SVAL(req.vwv+0, 0);
2700 if (num_replies != 1) {
2701 /* Not a Windows "Hey, you're still there?" request */
2702 return false;
2705 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2706 1, req.buflen)) {
2707 DEBUG(10, ("create_outbuf failed\n"));
2708 return false;
2710 req.outbuf = (uint8_t *)outbuf;
2712 SSVAL(req.outbuf, smb_vwv0, num_replies);
2714 if (req.buflen > 0) {
2715 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2718 out_len = smb_len(req.outbuf) + 4;
2720 ok = srv_send_smb(req.sconn,
2721 (char *)outbuf,
2722 true, seqnum+1,
2723 false, &req.pcd);
2724 TALLOC_FREE(outbuf);
2725 if (!ok) {
2726 exit(1);
2729 return true;
2732 static void smbd_echo_exit(struct tevent_context *ev,
2733 struct tevent_fd *fde, uint16_t flags,
2734 void *private_data)
2736 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2737 exit(0);
2740 static void smbd_echo_got_packet(struct tevent_req *req);
2742 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2743 int parent_pipe)
2745 struct smbd_echo_state *state;
2746 struct tevent_req *read_req;
2748 state = talloc_zero(sconn, struct smbd_echo_state);
2749 if (state == NULL) {
2750 DEBUG(1, ("talloc failed\n"));
2751 return;
2753 state->sconn = sconn;
2754 state->parent_pipe = parent_pipe;
2755 state->ev = s3_tevent_context_init(state);
2756 if (state->ev == NULL) {
2757 DEBUG(1, ("tevent_context_init failed\n"));
2758 TALLOC_FREE(state);
2759 return;
2761 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2762 TEVENT_FD_READ, smbd_echo_exit,
2763 state);
2764 if (state->parent_fde == NULL) {
2765 DEBUG(1, ("tevent_add_fd failed\n"));
2766 TALLOC_FREE(state);
2767 return;
2770 read_req = smbd_echo_read_send(state, state->ev, sconn);
2771 if (read_req == NULL) {
2772 DEBUG(1, ("smbd_echo_read_send failed\n"));
2773 TALLOC_FREE(state);
2774 return;
2776 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2778 while (true) {
2779 if (tevent_loop_once(state->ev) == -1) {
2780 DEBUG(1, ("tevent_loop_once failed: %s\n",
2781 strerror(errno)));
2782 break;
2785 TALLOC_FREE(state);
2788 static void smbd_echo_got_packet(struct tevent_req *req)
2790 struct smbd_echo_state *state = tevent_req_callback_data(
2791 req, struct smbd_echo_state);
2792 NTSTATUS status;
2793 char *buf = NULL;
2794 size_t buflen = 0;
2795 uint32_t seqnum = 0;
2796 bool reply;
2798 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2799 TALLOC_FREE(req);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2802 nt_errstr(status)));
2803 exit(1);
2806 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2807 if (!reply) {
2808 size_t num_pending;
2809 struct iovec *tmp;
2810 struct iovec *iov;
2812 num_pending = talloc_array_length(state->pending);
2813 tmp = talloc_realloc(state, state->pending, struct iovec,
2814 num_pending+1);
2815 if (tmp == NULL) {
2816 DEBUG(1, ("talloc_realloc failed\n"));
2817 exit(1);
2819 state->pending = tmp;
2821 if (buflen >= smb_size) {
2823 * place the seqnum in the packet so that the main process
2824 * can reply with signing
2826 SIVAL(buf, smb_ss_field, seqnum);
2827 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2830 iov = &state->pending[num_pending];
2831 iov->iov_base = buf;
2832 iov->iov_len = buflen;
2834 DEBUG(10,("echo_handler[%d]: forward to main\n",
2835 (int)sys_getpid()));
2836 smbd_echo_activate_writer(state);
2839 req = smbd_echo_read_send(state, state->ev, state->sconn);
2840 if (req == NULL) {
2841 DEBUG(1, ("smbd_echo_read_send failed\n"));
2842 exit(1);
2844 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2849 * Handle SMBecho requests in a forked child process
2851 bool fork_echo_handler(struct smbd_server_connection *sconn)
2853 int listener_pipe[2];
2854 int res;
2855 pid_t child;
2857 res = pipe(listener_pipe);
2858 if (res == -1) {
2859 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2860 return false;
2862 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2863 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2864 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2865 goto fail;
2868 child = sys_fork();
2869 if (child == 0) {
2870 NTSTATUS status;
2872 close(listener_pipe[0]);
2873 set_blocking(listener_pipe[1], false);
2875 status = reinit_after_fork(sconn->msg_ctx,
2876 server_event_context(),
2877 procid_self(), false);
2878 if (!NT_STATUS_IS_OK(status)) {
2879 DEBUG(1, ("reinit_after_fork failed: %s\n",
2880 nt_errstr(status)));
2881 exit(1);
2883 smbd_echo_loop(sconn, listener_pipe[1]);
2884 exit(0);
2886 close(listener_pipe[1]);
2887 listener_pipe[1] = -1;
2888 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2890 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2893 * Without smb signing this is the same as the normal smbd
2894 * listener. This needs to change once signing comes in.
2896 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2897 sconn,
2898 sconn->smb1.echo_handler.trusted_fd,
2899 EVENT_FD_READ,
2900 smbd_server_echo_handler,
2901 sconn);
2902 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2903 DEBUG(1, ("event_add_fd failed\n"));
2904 goto fail;
2907 return true;
2909 fail:
2910 if (listener_pipe[0] != -1) {
2911 close(listener_pipe[0]);
2913 if (listener_pipe[1] != -1) {
2914 close(listener_pipe[1]);
2916 sconn->smb1.echo_handler.trusted_fd = -1;
2917 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2918 close(sconn->smb1.echo_handler.socket_lock_fd);
2920 sconn->smb1.echo_handler.trusted_fd = -1;
2921 sconn->smb1.echo_handler.socket_lock_fd = -1;
2922 return false;
2925 #if CLUSTER_SUPPORT
2927 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2928 struct sockaddr_storage *srv,
2929 struct sockaddr_storage *clnt)
2931 struct ctdbd_connection *cconn;
2932 char tmp_addr[INET6_ADDRSTRLEN];
2933 char *addr;
2935 cconn = messaging_ctdbd_connection();
2936 if (cconn == NULL) {
2937 return NT_STATUS_NO_MEMORY;
2940 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2941 addr = talloc_strdup(cconn, tmp_addr);
2942 if (addr == NULL) {
2943 return NT_STATUS_NO_MEMORY;
2945 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2948 #endif
2950 /****************************************************************************
2951 Process commands from the client
2952 ****************************************************************************/
2954 void smbd_process(struct tevent_context *ev_ctx,
2955 struct smbd_server_connection *sconn)
2957 TALLOC_CTX *frame = talloc_stackframe();
2958 struct sockaddr_storage ss;
2959 struct sockaddr *sa = NULL;
2960 socklen_t sa_socklen;
2961 struct tsocket_address *local_address = NULL;
2962 struct tsocket_address *remote_address = NULL;
2963 const char *remaddr = NULL;
2964 char *rhost;
2965 int ret;
2967 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2969 * We're not making the decision here,
2970 * we're just allowing the client
2971 * to decide between SMB1 and SMB2
2972 * with the first negprot
2973 * packet.
2975 sconn->using_smb2 = true;
2978 /* Ensure child is set to blocking mode */
2979 set_blocking(sconn->sock,True);
2981 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2982 set_socket_options(sconn->sock, lp_socket_options());
2984 sa = (struct sockaddr *)(void *)&ss;
2985 sa_socklen = sizeof(ss);
2986 ret = getpeername(sconn->sock, sa, &sa_socklen);
2987 if (ret != 0) {
2988 int level = (errno == ENOTCONN)?2:0;
2989 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2990 exit_server_cleanly("getpeername() failed.\n");
2992 ret = tsocket_address_bsd_from_sockaddr(sconn,
2993 sa, sa_socklen,
2994 &remote_address);
2995 if (ret != 0) {
2996 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2997 __location__, strerror(errno)));
2998 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3001 sa = (struct sockaddr *)(void *)&ss;
3002 sa_socklen = sizeof(ss);
3003 ret = getsockname(sconn->sock, sa, &sa_socklen);
3004 if (ret != 0) {
3005 int level = (errno == ENOTCONN)?2:0;
3006 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3007 exit_server_cleanly("getsockname() failed.\n");
3009 ret = tsocket_address_bsd_from_sockaddr(sconn,
3010 sa, sa_socklen,
3011 &local_address);
3012 if (ret != 0) {
3013 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3014 __location__, strerror(errno)));
3015 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3018 sconn->local_address = local_address;
3019 sconn->remote_address = remote_address;
3021 if (tsocket_address_is_inet(remote_address, "ip")) {
3022 remaddr = tsocket_address_inet_addr_string(
3023 sconn->remote_address,
3024 talloc_tos());
3025 if (remaddr == NULL) {
3026 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3027 __location__, strerror(errno)));
3028 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3030 } else {
3031 remaddr = "0.0.0.0";
3034 /* this is needed so that we get decent entries
3035 in smbstatus for port 445 connects */
3036 set_remote_machine_name(remaddr, false);
3037 reload_services(sconn->msg_ctx, sconn->sock, true);
3040 * Before the first packet, check the global hosts allow/ hosts deny
3041 * parameters before doing any parsing of packets passed to us by the
3042 * client. This prevents attacks on our parsing code from hosts not in
3043 * the hosts allow list.
3046 ret = get_remote_hostname(remote_address,
3047 &rhost,
3048 talloc_tos());
3049 if (ret < 0) {
3050 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3051 __location__, strerror(errno)));
3052 exit_server_cleanly("get_remote_hostname failed.\n");
3054 if (strequal(rhost, "UNKNOWN")) {
3055 rhost = talloc_strdup(talloc_tos(), remaddr);
3057 sconn->remote_hostname = talloc_move(sconn, &rhost);
3059 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3060 sconn->remote_hostname,
3061 remaddr)) {
3063 * send a negative session response "not listening on calling
3064 * name"
3066 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3067 DEBUG( 1, ("Connection denied from %s to %s\n",
3068 tsocket_address_string(remote_address, talloc_tos()),
3069 tsocket_address_string(local_address, talloc_tos())));
3070 (void)srv_send_smb(sconn,(char *)buf, false,
3071 0, false, NULL);
3072 exit_server_cleanly("connection denied");
3075 DEBUG(10, ("Connection allowed from %s to %s\n",
3076 tsocket_address_string(remote_address, talloc_tos()),
3077 tsocket_address_string(local_address, talloc_tos())));
3079 init_modules();
3081 smb_perfcount_init();
3083 if (!init_account_policy()) {
3084 exit_server("Could not open account policy tdb.\n");
3087 if (*lp_rootdir()) {
3088 if (chroot(lp_rootdir()) != 0) {
3089 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3090 exit_server("Failed to chroot()");
3092 if (chdir("/") == -1) {
3093 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3094 exit_server("Failed to chroot()");
3096 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3099 if (!srv_init_signing(sconn)) {
3100 exit_server("Failed to init smb_signing");
3103 /* Setup oplocks */
3104 if (!init_oplocks(sconn->msg_ctx))
3105 exit_server("Failed to init oplocks");
3107 /* register our message handlers */
3108 messaging_register(sconn->msg_ctx, NULL,
3109 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3110 messaging_register(sconn->msg_ctx, NULL,
3111 MSG_SMB_CLOSE_FILE, msg_close_file);
3114 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3115 * MSGs to all child processes
3117 messaging_deregister(sconn->msg_ctx,
3118 MSG_DEBUG, NULL);
3119 messaging_register(sconn->msg_ctx, NULL,
3120 MSG_DEBUG, debug_message);
3122 if ((lp_keepalive() != 0)
3123 && !(event_add_idle(ev_ctx, NULL,
3124 timeval_set(lp_keepalive(), 0),
3125 "keepalive", keepalive_fn,
3126 sconn))) {
3127 DEBUG(0, ("Could not add keepalive event\n"));
3128 exit(1);
3131 if (!(event_add_idle(ev_ctx, NULL,
3132 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3133 "deadtime", deadtime_fn, sconn))) {
3134 DEBUG(0, ("Could not add deadtime event\n"));
3135 exit(1);
3138 if (!(event_add_idle(ev_ctx, NULL,
3139 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3140 "housekeeping", housekeeping_fn, sconn))) {
3141 DEBUG(0, ("Could not add housekeeping event\n"));
3142 exit(1);
3145 #ifdef CLUSTER_SUPPORT
3147 if (lp_clustering()) {
3149 * We need to tell ctdb about our client's TCP
3150 * connection, so that for failover ctdbd can send
3151 * tickle acks, triggering a reconnection by the
3152 * client.
3155 struct sockaddr_storage srv, clnt;
3157 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3158 NTSTATUS status;
3159 status = smbd_register_ips(sconn, &srv, &clnt);
3160 if (!NT_STATUS_IS_OK(status)) {
3161 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3162 nt_errstr(status)));
3164 } else
3166 DEBUG(0,("Unable to get tcp info for "
3167 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3168 strerror(errno)));
3172 #endif
3174 sconn->nbt.got_session = false;
3176 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3178 sconn->smb1.sessions.done_sesssetup = false;
3179 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3180 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3181 /* users from session setup */
3182 sconn->smb1.sessions.session_userlist = NULL;
3183 /* workgroup from session setup. */
3184 sconn->smb1.sessions.session_workgroup = NULL;
3185 /* this holds info on user ids that are already validated for this VC */
3186 sconn->smb1.sessions.validated_users = NULL;
3187 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3188 sconn->smb1.sessions.num_validated_vuids = 0;
3190 conn_init(sconn);
3191 if (!init_dptrs(sconn)) {
3192 exit_server("init_dptrs() failed");
3195 sconn->smb1.fde = event_add_fd(ev_ctx,
3196 sconn,
3197 sconn->sock,
3198 EVENT_FD_READ,
3199 smbd_server_connection_handler,
3200 sconn);
3201 if (!sconn->smb1.fde) {
3202 exit_server("failed to create smbd_server_connection fde");
3205 TALLOC_FREE(frame);
3207 while (True) {
3208 NTSTATUS status;
3210 frame = talloc_stackframe_pool(8192);
3212 errno = 0;
3214 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3215 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3216 !NT_STATUS_IS_OK(status)) {
3217 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3218 " exiting\n", nt_errstr(status)));
3219 break;
3222 TALLOC_FREE(frame);
3225 exit_server_cleanly(NULL);
3228 bool req_is_in_chain(struct smb_request *req)
3230 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3232 * We're right now handling a subsequent request, so we must
3233 * be in a chain
3235 return true;
3238 if (!is_andx_req(req->cmd)) {
3239 return false;
3242 if (req->wct < 2) {
3244 * Okay, an illegal request, but definitely not chained :-)
3246 return false;
3249 return (CVAL(req->vwv+0, 0) != 0xFF);