s3: Fix the read&x offset within a chain
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blobc163212bc0dd5c901d3f95a3fd78e5f45f6c099c
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 extern bool global_machine_password_needs_changing;
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct timed_event *te;
51 struct smb_perfcount_data pcd;
52 uint32_t seqnum;
53 bool encrypted;
54 bool processed;
55 DATA_BLOB buf;
56 DATA_BLOB private_data;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
60 char *outbuf);
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
63 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
65 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
67 bool ok;
69 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
70 return true;
73 sconn->smb1.echo_handler.ref_count++;
75 if (sconn->smb1.echo_handler.ref_count > 1) {
76 return true;
79 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
81 do {
82 ok = fcntl_lock(
83 sconn->smb1.echo_handler.socket_lock_fd,
84 SMB_F_SETLKW, 0, 0, F_WRLCK);
85 } while (!ok && (errno == EINTR));
87 if (!ok) {
88 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
89 return false;
92 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
94 return true;
97 void smbd_lock_socket(struct smbd_server_connection *sconn)
99 if (!smbd_lock_socket_internal(sconn)) {
100 exit_server_cleanly("failed to lock socket");
104 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
106 bool ok;
108 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
109 return true;
112 sconn->smb1.echo_handler.ref_count--;
114 if (sconn->smb1.echo_handler.ref_count > 0) {
115 return true;
118 do {
119 ok = fcntl_lock(
120 sconn->smb1.echo_handler.socket_lock_fd,
121 SMB_F_SETLKW, 0, 0, F_UNLCK);
122 } while (!ok && (errno == EINTR));
124 if (!ok) {
125 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
126 return false;
129 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
131 return true;
134 void smbd_unlock_socket(struct smbd_server_connection *sconn)
136 if (!smbd_unlock_socket_internal(sconn)) {
137 exit_server_cleanly("failed to unlock socket");
141 /* Accessor function for smb_read_error for smbd functions. */
143 /****************************************************************************
144 Send an smb to a fd.
145 ****************************************************************************/
147 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
148 bool do_signing, uint32_t seqnum,
149 bool do_encrypt,
150 struct smb_perfcount_data *pcd)
152 size_t len = 0;
153 size_t nwritten=0;
154 ssize_t ret;
155 char *buf_out = buffer;
157 smbd_lock_socket(sconn);
159 if (do_signing) {
160 /* Sign the outgoing packet if required. */
161 srv_calculate_sign_mac(sconn, buf_out, seqnum);
164 if (do_encrypt) {
165 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
166 if (!NT_STATUS_IS_OK(status)) {
167 DEBUG(0, ("send_smb: SMB encryption failed "
168 "on outgoing packet! Error %s\n",
169 nt_errstr(status) ));
170 goto out;
174 len = smb_len(buf_out) + 4;
176 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
177 if (ret <= 0) {
179 char addr[INET6_ADDRSTRLEN];
181 * Try and give an error message saying what
182 * client failed.
184 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
185 (int)sys_getpid(), (int)len,
186 get_peer_addr(sconn->sock, addr, sizeof(addr)),
187 (int)ret, strerror(errno) ));
189 srv_free_enc_buffer(sconn, buf_out);
190 goto out;
193 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
194 srv_free_enc_buffer(sconn, buf_out);
195 out:
196 SMB_PERFCOUNT_END(pcd);
198 smbd_unlock_socket(sconn);
199 return true;
202 /*******************************************************************
203 Setup the word count and byte count for a smb message.
204 ********************************************************************/
206 int srv_set_message(char *buf,
207 int num_words,
208 int num_bytes,
209 bool zero)
211 if (zero && (num_words || num_bytes)) {
212 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
214 SCVAL(buf,smb_wct,num_words);
215 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
216 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
217 return (smb_size + num_words*2 + num_bytes);
220 static bool valid_smb_header(struct smbd_server_connection *sconn,
221 const uint8_t *inbuf)
223 if (is_encrypted_packet(sconn, inbuf)) {
224 return true;
227 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
228 * but it just looks weird to call strncmp for this one.
230 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
233 /* Socket functions for smbd packet processing. */
235 static bool valid_packet_size(size_t len)
238 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
239 * of header. Don't print the error if this fits.... JRA.
242 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
243 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
244 (unsigned long)len));
245 return false;
247 return true;
250 static NTSTATUS read_packet_remainder(int fd, char *buffer,
251 unsigned int timeout, ssize_t len)
253 NTSTATUS status;
255 if (len <= 0) {
256 return NT_STATUS_OK;
259 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
260 if (!NT_STATUS_IS_OK(status)) {
261 char addr[INET6_ADDRSTRLEN];
262 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
263 "error = %s.\n",
264 get_peer_addr(fd, addr, sizeof(addr)),
265 nt_errstr(status)));
267 return status;
270 /****************************************************************************
271 Attempt a zerocopy writeX read. We know here that len > smb_size-4
272 ****************************************************************************/
275 * Unfortunately, earlier versions of smbclient/libsmbclient
276 * don't send this "standard" writeX header. I've fixed this
277 * for 3.2 but we'll use the old method with earlier versions.
278 * Windows and CIFSFS at least use this standard size. Not
279 * sure about MacOSX.
282 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
283 (2*14) + /* word count (including bcc) */ \
284 1 /* pad byte */)
286 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
287 const char lenbuf[4],
288 struct smbd_server_connection *sconn,
289 int sock,
290 char **buffer,
291 unsigned int timeout,
292 size_t *p_unread,
293 size_t *len_ret)
295 /* Size of a WRITEX call (+4 byte len). */
296 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
297 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
298 ssize_t toread;
299 NTSTATUS status;
301 memcpy(writeX_header, lenbuf, 4);
303 status = read_fd_with_timeout(
304 sock, writeX_header + 4,
305 STANDARD_WRITE_AND_X_HEADER_SIZE,
306 STANDARD_WRITE_AND_X_HEADER_SIZE,
307 timeout, NULL);
309 if (!NT_STATUS_IS_OK(status)) {
310 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
311 "error = %s.\n",
312 tsocket_address_string(sconn->remote_address,
313 talloc_tos()),
314 nt_errstr(status)));
315 return status;
319 * Ok - now try and see if this is a possible
320 * valid writeX call.
323 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
325 * If the data offset is beyond what
326 * we've read, drain the extra bytes.
328 uint16_t doff = SVAL(writeX_header,smb_vwv11);
329 ssize_t newlen;
331 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
332 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
333 if (drain_socket(sock, drain) != drain) {
334 smb_panic("receive_smb_raw_talloc_partial_read:"
335 " failed to drain pending bytes");
337 } else {
338 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
341 /* Spoof down the length and null out the bcc. */
342 set_message_bcc(writeX_header, 0);
343 newlen = smb_len(writeX_header);
345 /* Copy the header we've written. */
347 *buffer = (char *)talloc_memdup(mem_ctx,
348 writeX_header,
349 sizeof(writeX_header));
351 if (*buffer == NULL) {
352 DEBUG(0, ("Could not allocate inbuf of length %d\n",
353 (int)sizeof(writeX_header)));
354 return NT_STATUS_NO_MEMORY;
357 /* Work out the remaining bytes. */
358 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
359 *len_ret = newlen + 4;
360 return NT_STATUS_OK;
363 if (!valid_packet_size(len)) {
364 return NT_STATUS_INVALID_PARAMETER;
368 * Not a valid writeX call. Just do the standard
369 * talloc and return.
372 *buffer = talloc_array(mem_ctx, char, len+4);
374 if (*buffer == NULL) {
375 DEBUG(0, ("Could not allocate inbuf of length %d\n",
376 (int)len+4));
377 return NT_STATUS_NO_MEMORY;
380 /* Copy in what we already read. */
381 memcpy(*buffer,
382 writeX_header,
383 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
384 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
386 if(toread > 0) {
387 status = read_packet_remainder(
388 sock,
389 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
390 timeout, toread);
392 if (!NT_STATUS_IS_OK(status)) {
393 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
394 nt_errstr(status)));
395 return status;
399 *len_ret = len + 4;
400 return NT_STATUS_OK;
403 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
404 struct smbd_server_connection *sconn,
405 int sock,
406 char **buffer, unsigned int timeout,
407 size_t *p_unread, size_t *plen)
409 char lenbuf[4];
410 size_t len;
411 int min_recv_size = lp_min_receive_file_size();
412 NTSTATUS status;
414 *p_unread = 0;
416 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
417 &len);
418 if (!NT_STATUS_IS_OK(status)) {
419 return status;
422 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
423 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
424 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
425 !srv_is_signing_active(sconn) &&
426 sconn->smb1.echo_handler.trusted_fde == NULL) {
428 return receive_smb_raw_talloc_partial_read(
429 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
430 p_unread, plen);
433 if (!valid_packet_size(len)) {
434 return NT_STATUS_INVALID_PARAMETER;
438 * The +4 here can't wrap, we've checked the length above already.
441 *buffer = talloc_array(mem_ctx, char, len+4);
443 if (*buffer == NULL) {
444 DEBUG(0, ("Could not allocate inbuf of length %d\n",
445 (int)len+4));
446 return NT_STATUS_NO_MEMORY;
449 memcpy(*buffer, lenbuf, sizeof(lenbuf));
451 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
452 if (!NT_STATUS_IS_OK(status)) {
453 return status;
456 *plen = len + 4;
457 return NT_STATUS_OK;
460 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
461 struct smbd_server_connection *sconn,
462 int sock,
463 char **buffer, unsigned int timeout,
464 size_t *p_unread, bool *p_encrypted,
465 size_t *p_len,
466 uint32_t *seqnum,
467 bool trusted_channel)
469 size_t len = 0;
470 NTSTATUS status;
472 *p_encrypted = false;
474 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
475 p_unread, &len);
476 if (!NT_STATUS_IS_OK(status)) {
477 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
478 ("receive_smb_raw_talloc failed for client %s "
479 "read error = %s.\n",
480 tsocket_address_string(sconn->remote_address,
481 talloc_tos()),
482 nt_errstr(status)) );
483 return status;
486 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
487 status = srv_decrypt_buffer(sconn, *buffer);
488 if (!NT_STATUS_IS_OK(status)) {
489 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
490 "incoming packet! Error %s\n",
491 nt_errstr(status) ));
492 return status;
494 *p_encrypted = true;
497 /* Check the incoming SMB signature. */
498 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
499 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
500 "incoming packet!\n"));
501 return NT_STATUS_INVALID_NETWORK_RESPONSE;
504 *p_len = len;
505 return NT_STATUS_OK;
509 * Initialize a struct smb_request from an inbuf
512 static bool init_smb_request(struct smb_request *req,
513 struct smbd_server_connection *sconn,
514 const uint8 *inbuf,
515 size_t unread_bytes, bool encrypted,
516 uint32_t seqnum)
518 size_t req_size = smb_len(inbuf) + 4;
519 /* Ensure we have at least smb_size bytes. */
520 if (req_size < smb_size) {
521 DEBUG(0,("init_smb_request: invalid request size %u\n",
522 (unsigned int)req_size ));
523 return false;
525 req->cmd = CVAL(inbuf, smb_com);
526 req->flags2 = SVAL(inbuf, smb_flg2);
527 req->smbpid = SVAL(inbuf, smb_pid);
528 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
529 req->seqnum = seqnum;
530 req->vuid = SVAL(inbuf, smb_uid);
531 req->tid = SVAL(inbuf, smb_tid);
532 req->wct = CVAL(inbuf, smb_wct);
533 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
534 req->buflen = smb_buflen(inbuf);
535 req->buf = (const uint8_t *)smb_buf_const(inbuf);
536 req->unread_bytes = unread_bytes;
537 req->encrypted = encrypted;
538 req->sconn = sconn;
539 req->conn = conn_find(sconn,req->tid);
540 req->chain_fsp = NULL;
541 req->chain_outbuf = NULL;
542 req->done = false;
543 req->smb2req = NULL;
544 req->priv_paths = NULL;
545 smb_init_perfcount_data(&req->pcd);
547 /* Ensure we have at least wct words and 2 bytes of bcc. */
548 if (smb_size + req->wct*2 > req_size) {
549 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
550 (unsigned int)req->wct,
551 (unsigned int)req_size));
552 return false;
554 /* Ensure bcc is correct. */
555 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
556 DEBUG(0,("init_smb_request: invalid bcc number %u "
557 "(wct = %u, size %u)\n",
558 (unsigned int)req->buflen,
559 (unsigned int)req->wct,
560 (unsigned int)req_size));
561 return false;
564 req->outbuf = NULL;
565 return true;
568 static void process_smb(struct smbd_server_connection *conn,
569 uint8_t *inbuf, size_t nread, size_t unread_bytes,
570 uint32_t seqnum, bool encrypted,
571 struct smb_perfcount_data *deferred_pcd);
573 static void smbd_deferred_open_timer(struct event_context *ev,
574 struct timed_event *te,
575 struct timeval _tval,
576 void *private_data)
578 struct pending_message_list *msg = talloc_get_type(private_data,
579 struct pending_message_list);
580 struct smbd_server_connection *sconn = msg->sconn;
581 TALLOC_CTX *mem_ctx = talloc_tos();
582 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
583 uint8_t *inbuf;
585 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
586 msg->buf.length);
587 if (inbuf == NULL) {
588 exit_server("smbd_deferred_open_timer: talloc failed\n");
589 return;
592 /* We leave this message on the queue so the open code can
593 know this is a retry. */
594 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
595 (unsigned long long)mid ));
597 /* Mark the message as processed so this is not
598 * re-processed in error. */
599 msg->processed = true;
601 process_smb(sconn, inbuf,
602 msg->buf.length, 0,
603 msg->seqnum, msg->encrypted, &msg->pcd);
605 /* If it's still there and was processed, remove it. */
606 msg = get_deferred_open_message_smb(sconn, mid);
607 if (msg && msg->processed) {
608 remove_deferred_open_message_smb(sconn, mid);
612 /****************************************************************************
613 Function to push a message onto the tail of a linked list of smb messages ready
614 for processing.
615 ****************************************************************************/
617 static bool push_queued_message(struct smb_request *req,
618 struct timeval request_time,
619 struct timeval end_time,
620 char *private_data, size_t private_len)
622 int msg_len = smb_len(req->inbuf) + 4;
623 struct pending_message_list *msg;
625 msg = talloc_zero(NULL, struct pending_message_list);
627 if(msg == NULL) {
628 DEBUG(0,("push_message: malloc fail (1)\n"));
629 return False;
631 msg->sconn = req->sconn;
633 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
634 if(msg->buf.data == NULL) {
635 DEBUG(0,("push_message: malloc fail (2)\n"));
636 TALLOC_FREE(msg);
637 return False;
640 msg->request_time = request_time;
641 msg->seqnum = req->seqnum;
642 msg->encrypted = req->encrypted;
643 msg->processed = false;
644 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
646 if (private_data) {
647 msg->private_data = data_blob_talloc(msg, private_data,
648 private_len);
649 if (msg->private_data.data == NULL) {
650 DEBUG(0,("push_message: malloc fail (3)\n"));
651 TALLOC_FREE(msg);
652 return False;
656 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
657 msg,
658 end_time,
659 smbd_deferred_open_timer,
660 msg);
661 if (!msg->te) {
662 DEBUG(0,("push_message: event_add_timed failed\n"));
663 TALLOC_FREE(msg);
664 return false;
667 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
668 struct pending_message_list *);
670 DEBUG(10,("push_message: pushed message length %u on "
671 "deferred_open_queue\n", (unsigned int)msg_len));
673 return True;
676 /****************************************************************************
677 Function to delete a sharing violation open message by mid.
678 ****************************************************************************/
680 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
681 uint64_t mid)
683 struct pending_message_list *pml;
685 if (sconn->using_smb2) {
686 remove_deferred_open_message_smb2(sconn, mid);
687 return;
690 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
691 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
692 DEBUG(10,("remove_deferred_open_message_smb: "
693 "deleting mid %llu len %u\n",
694 (unsigned long long)mid,
695 (unsigned int)pml->buf.length ));
696 DLIST_REMOVE(sconn->deferred_open_queue, pml);
697 TALLOC_FREE(pml);
698 return;
703 /****************************************************************************
704 Move a sharing violation open retry message to the front of the list and
705 schedule it for immediate processing.
706 ****************************************************************************/
708 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
709 uint64_t mid)
711 struct pending_message_list *pml;
712 int i = 0;
714 if (sconn->using_smb2) {
715 schedule_deferred_open_message_smb2(sconn, mid);
716 return;
719 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
720 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
722 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
723 "msg_mid = %llu\n",
724 i++,
725 (unsigned long long)msg_mid ));
727 if (mid == msg_mid) {
728 struct timed_event *te;
730 if (pml->processed) {
731 /* A processed message should not be
732 * rescheduled. */
733 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
734 "message mid %llu was already processed\n",
735 (unsigned long long)msg_mid ));
736 continue;
739 DEBUG(10,("schedule_deferred_open_message_smb: "
740 "scheduling mid %llu\n",
741 (unsigned long long)mid ));
743 te = tevent_add_timer(pml->sconn->ev_ctx,
744 pml,
745 timeval_zero(),
746 smbd_deferred_open_timer,
747 pml);
748 if (!te) {
749 DEBUG(10,("schedule_deferred_open_message_smb: "
750 "event_add_timed() failed, "
751 "skipping mid %llu\n",
752 (unsigned long long)msg_mid ));
755 TALLOC_FREE(pml->te);
756 pml->te = te;
757 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
758 return;
762 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
763 "find message mid %llu\n",
764 (unsigned long long)mid ));
767 /****************************************************************************
768 Return true if this mid is on the deferred queue and was not yet processed.
769 ****************************************************************************/
771 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
773 struct pending_message_list *pml;
775 if (sconn->using_smb2) {
776 return open_was_deferred_smb2(sconn, mid);
779 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
780 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
781 return True;
784 return False;
787 /****************************************************************************
788 Return the message queued by this mid.
789 ****************************************************************************/
791 static struct pending_message_list *get_deferred_open_message_smb(
792 struct smbd_server_connection *sconn, uint64_t mid)
794 struct pending_message_list *pml;
796 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
797 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
798 return pml;
801 return NULL;
804 /****************************************************************************
805 Get the state data queued by this mid.
806 ****************************************************************************/
808 bool get_deferred_open_message_state(struct smb_request *smbreq,
809 struct timeval *p_request_time,
810 void **pp_state)
812 struct pending_message_list *pml;
814 if (smbreq->sconn->using_smb2) {
815 return get_deferred_open_message_state_smb2(smbreq->smb2req,
816 p_request_time,
817 pp_state);
820 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
821 if (!pml) {
822 return false;
824 if (p_request_time) {
825 *p_request_time = pml->request_time;
827 if (pp_state) {
828 *pp_state = (void *)pml->private_data.data;
830 return true;
833 /****************************************************************************
834 Function to push a deferred open smb message onto a linked list of local smb
835 messages ready for processing.
836 ****************************************************************************/
838 bool push_deferred_open_message_smb(struct smb_request *req,
839 struct timeval request_time,
840 struct timeval timeout,
841 struct file_id id,
842 char *private_data, size_t priv_len)
844 struct timeval end_time;
846 if (req->smb2req) {
847 return push_deferred_open_message_smb2(req->smb2req,
848 request_time,
849 timeout,
851 private_data,
852 priv_len);
855 if (req->unread_bytes) {
856 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
857 "unread_bytes = %u\n",
858 (unsigned int)req->unread_bytes ));
859 smb_panic("push_deferred_open_message_smb: "
860 "logic error unread_bytes != 0" );
863 end_time = timeval_sum(&request_time, &timeout);
865 DEBUG(10,("push_deferred_open_message_smb: pushing message "
866 "len %u mid %llu timeout time [%u.%06u]\n",
867 (unsigned int) smb_len(req->inbuf)+4,
868 (unsigned long long)req->mid,
869 (unsigned int)end_time.tv_sec,
870 (unsigned int)end_time.tv_usec));
872 return push_queued_message(req, request_time, end_time,
873 private_data, priv_len);
876 static void smbd_sig_term_handler(struct tevent_context *ev,
877 struct tevent_signal *se,
878 int signum,
879 int count,
880 void *siginfo,
881 void *private_data)
883 exit_server_cleanly("termination signal");
886 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
888 struct tevent_signal *se;
890 se = tevent_add_signal(sconn->ev_ctx,
891 sconn,
892 SIGTERM, 0,
893 smbd_sig_term_handler,
894 sconn);
895 if (!se) {
896 exit_server("failed to setup SIGTERM handler");
900 static void smbd_sig_hup_handler(struct tevent_context *ev,
901 struct tevent_signal *se,
902 int signum,
903 int count,
904 void *siginfo,
905 void *private_data)
907 struct smbd_server_connection *sconn =
908 talloc_get_type_abort(private_data,
909 struct smbd_server_connection);
911 change_to_root_user();
912 DEBUG(1,("Reloading services after SIGHUP\n"));
913 reload_services(sconn, conn_snum_used, false);
916 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
918 struct tevent_signal *se;
920 se = tevent_add_signal(sconn->ev_ctx,
921 sconn,
922 SIGHUP, 0,
923 smbd_sig_hup_handler,
924 sconn);
925 if (!se) {
926 exit_server("failed to setup SIGHUP handler");
930 static void smbd_conf_updated(struct messaging_context *msg,
931 void *private_data,
932 uint32_t msg_type,
933 struct server_id server_id,
934 DATA_BLOB *data)
936 struct smbd_server_connection *sconn =
937 talloc_get_type_abort(private_data,
938 struct smbd_server_connection);
940 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
941 "updated. Reloading.\n"));
942 change_to_root_user();
943 reload_services(sconn, conn_snum_used, false);
947 * Only allow 5 outstanding trans requests. We're allocating memory, so
948 * prevent a DoS.
951 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
953 int count = 0;
954 for (; list != NULL; list = list->next) {
956 if (list->mid == mid) {
957 return NT_STATUS_INVALID_PARAMETER;
960 count += 1;
962 if (count > 5) {
963 return NT_STATUS_INSUFFICIENT_RESOURCES;
966 return NT_STATUS_OK;
970 These flags determine some of the permissions required to do an operation
972 Note that I don't set NEED_WRITE on some write operations because they
973 are used by some brain-dead clients when printing, and I don't want to
974 force write permissions on print services.
976 #define AS_USER (1<<0)
977 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
978 #define TIME_INIT (1<<2)
979 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
980 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
981 #define DO_CHDIR (1<<6)
984 define a list of possible SMB messages and their corresponding
985 functions. Any message that has a NULL function is unimplemented -
986 please feel free to contribute implementations!
988 static const struct smb_message_struct {
989 const char *name;
990 void (*fn)(struct smb_request *req);
991 int flags;
992 } smb_messages[256] = {
994 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
995 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
996 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
997 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
998 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
999 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1000 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1001 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1002 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1003 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1004 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1005 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1006 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1007 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1008 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1009 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1010 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1011 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1012 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1013 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1014 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1015 /* 0x15 */ { NULL, NULL, 0 },
1016 /* 0x16 */ { NULL, NULL, 0 },
1017 /* 0x17 */ { NULL, NULL, 0 },
1018 /* 0x18 */ { NULL, NULL, 0 },
1019 /* 0x19 */ { NULL, NULL, 0 },
1020 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1021 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1022 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1023 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1024 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1025 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1026 /* 0x20 */ { "SMBwritec", NULL,0},
1027 /* 0x21 */ { NULL, NULL, 0 },
1028 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1029 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1030 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1031 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1032 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1033 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1034 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1035 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1036 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1037 /* 0x2b */ { "SMBecho",reply_echo,0},
1038 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1039 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1040 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1041 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1042 /* 0x30 */ { NULL, NULL, 0 },
1043 /* 0x31 */ { NULL, NULL, 0 },
1044 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1045 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1046 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1047 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1048 /* 0x36 */ { NULL, NULL, 0 },
1049 /* 0x37 */ { NULL, NULL, 0 },
1050 /* 0x38 */ { NULL, NULL, 0 },
1051 /* 0x39 */ { NULL, NULL, 0 },
1052 /* 0x3a */ { NULL, NULL, 0 },
1053 /* 0x3b */ { NULL, NULL, 0 },
1054 /* 0x3c */ { NULL, NULL, 0 },
1055 /* 0x3d */ { NULL, NULL, 0 },
1056 /* 0x3e */ { NULL, NULL, 0 },
1057 /* 0x3f */ { NULL, NULL, 0 },
1058 /* 0x40 */ { NULL, NULL, 0 },
1059 /* 0x41 */ { NULL, NULL, 0 },
1060 /* 0x42 */ { NULL, NULL, 0 },
1061 /* 0x43 */ { NULL, NULL, 0 },
1062 /* 0x44 */ { NULL, NULL, 0 },
1063 /* 0x45 */ { NULL, NULL, 0 },
1064 /* 0x46 */ { NULL, NULL, 0 },
1065 /* 0x47 */ { NULL, NULL, 0 },
1066 /* 0x48 */ { NULL, NULL, 0 },
1067 /* 0x49 */ { NULL, NULL, 0 },
1068 /* 0x4a */ { NULL, NULL, 0 },
1069 /* 0x4b */ { NULL, NULL, 0 },
1070 /* 0x4c */ { NULL, NULL, 0 },
1071 /* 0x4d */ { NULL, NULL, 0 },
1072 /* 0x4e */ { NULL, NULL, 0 },
1073 /* 0x4f */ { NULL, NULL, 0 },
1074 /* 0x50 */ { NULL, NULL, 0 },
1075 /* 0x51 */ { NULL, NULL, 0 },
1076 /* 0x52 */ { NULL, NULL, 0 },
1077 /* 0x53 */ { NULL, NULL, 0 },
1078 /* 0x54 */ { NULL, NULL, 0 },
1079 /* 0x55 */ { NULL, NULL, 0 },
1080 /* 0x56 */ { NULL, NULL, 0 },
1081 /* 0x57 */ { NULL, NULL, 0 },
1082 /* 0x58 */ { NULL, NULL, 0 },
1083 /* 0x59 */ { NULL, NULL, 0 },
1084 /* 0x5a */ { NULL, NULL, 0 },
1085 /* 0x5b */ { NULL, NULL, 0 },
1086 /* 0x5c */ { NULL, NULL, 0 },
1087 /* 0x5d */ { NULL, NULL, 0 },
1088 /* 0x5e */ { NULL, NULL, 0 },
1089 /* 0x5f */ { NULL, NULL, 0 },
1090 /* 0x60 */ { NULL, NULL, 0 },
1091 /* 0x61 */ { NULL, NULL, 0 },
1092 /* 0x62 */ { NULL, NULL, 0 },
1093 /* 0x63 */ { NULL, NULL, 0 },
1094 /* 0x64 */ { NULL, NULL, 0 },
1095 /* 0x65 */ { NULL, NULL, 0 },
1096 /* 0x66 */ { NULL, NULL, 0 },
1097 /* 0x67 */ { NULL, NULL, 0 },
1098 /* 0x68 */ { NULL, NULL, 0 },
1099 /* 0x69 */ { NULL, NULL, 0 },
1100 /* 0x6a */ { NULL, NULL, 0 },
1101 /* 0x6b */ { NULL, NULL, 0 },
1102 /* 0x6c */ { NULL, NULL, 0 },
1103 /* 0x6d */ { NULL, NULL, 0 },
1104 /* 0x6e */ { NULL, NULL, 0 },
1105 /* 0x6f */ { NULL, NULL, 0 },
1106 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1107 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1108 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1109 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1110 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1111 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1112 /* 0x76 */ { NULL, NULL, 0 },
1113 /* 0x77 */ { NULL, NULL, 0 },
1114 /* 0x78 */ { NULL, NULL, 0 },
1115 /* 0x79 */ { NULL, NULL, 0 },
1116 /* 0x7a */ { NULL, NULL, 0 },
1117 /* 0x7b */ { NULL, NULL, 0 },
1118 /* 0x7c */ { NULL, NULL, 0 },
1119 /* 0x7d */ { NULL, NULL, 0 },
1120 /* 0x7e */ { NULL, NULL, 0 },
1121 /* 0x7f */ { NULL, NULL, 0 },
1122 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1123 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1124 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1125 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1126 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1127 /* 0x85 */ { NULL, NULL, 0 },
1128 /* 0x86 */ { NULL, NULL, 0 },
1129 /* 0x87 */ { NULL, NULL, 0 },
1130 /* 0x88 */ { NULL, NULL, 0 },
1131 /* 0x89 */ { NULL, NULL, 0 },
1132 /* 0x8a */ { NULL, NULL, 0 },
1133 /* 0x8b */ { NULL, NULL, 0 },
1134 /* 0x8c */ { NULL, NULL, 0 },
1135 /* 0x8d */ { NULL, NULL, 0 },
1136 /* 0x8e */ { NULL, NULL, 0 },
1137 /* 0x8f */ { NULL, NULL, 0 },
1138 /* 0x90 */ { NULL, NULL, 0 },
1139 /* 0x91 */ { NULL, NULL, 0 },
1140 /* 0x92 */ { NULL, NULL, 0 },
1141 /* 0x93 */ { NULL, NULL, 0 },
1142 /* 0x94 */ { NULL, NULL, 0 },
1143 /* 0x95 */ { NULL, NULL, 0 },
1144 /* 0x96 */ { NULL, NULL, 0 },
1145 /* 0x97 */ { NULL, NULL, 0 },
1146 /* 0x98 */ { NULL, NULL, 0 },
1147 /* 0x99 */ { NULL, NULL, 0 },
1148 /* 0x9a */ { NULL, NULL, 0 },
1149 /* 0x9b */ { NULL, NULL, 0 },
1150 /* 0x9c */ { NULL, NULL, 0 },
1151 /* 0x9d */ { NULL, NULL, 0 },
1152 /* 0x9e */ { NULL, NULL, 0 },
1153 /* 0x9f */ { NULL, NULL, 0 },
1154 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1155 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1156 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1157 /* 0xa3 */ { NULL, NULL, 0 },
1158 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1159 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1160 /* 0xa6 */ { NULL, NULL, 0 },
1161 /* 0xa7 */ { NULL, NULL, 0 },
1162 /* 0xa8 */ { NULL, NULL, 0 },
1163 /* 0xa9 */ { NULL, NULL, 0 },
1164 /* 0xaa */ { NULL, NULL, 0 },
1165 /* 0xab */ { NULL, NULL, 0 },
1166 /* 0xac */ { NULL, NULL, 0 },
1167 /* 0xad */ { NULL, NULL, 0 },
1168 /* 0xae */ { NULL, NULL, 0 },
1169 /* 0xaf */ { NULL, NULL, 0 },
1170 /* 0xb0 */ { NULL, NULL, 0 },
1171 /* 0xb1 */ { NULL, NULL, 0 },
1172 /* 0xb2 */ { NULL, NULL, 0 },
1173 /* 0xb3 */ { NULL, NULL, 0 },
1174 /* 0xb4 */ { NULL, NULL, 0 },
1175 /* 0xb5 */ { NULL, NULL, 0 },
1176 /* 0xb6 */ { NULL, NULL, 0 },
1177 /* 0xb7 */ { NULL, NULL, 0 },
1178 /* 0xb8 */ { NULL, NULL, 0 },
1179 /* 0xb9 */ { NULL, NULL, 0 },
1180 /* 0xba */ { NULL, NULL, 0 },
1181 /* 0xbb */ { NULL, NULL, 0 },
1182 /* 0xbc */ { NULL, NULL, 0 },
1183 /* 0xbd */ { NULL, NULL, 0 },
1184 /* 0xbe */ { NULL, NULL, 0 },
1185 /* 0xbf */ { NULL, NULL, 0 },
1186 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1187 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1188 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1189 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1190 /* 0xc4 */ { NULL, NULL, 0 },
1191 /* 0xc5 */ { NULL, NULL, 0 },
1192 /* 0xc6 */ { NULL, NULL, 0 },
1193 /* 0xc7 */ { NULL, NULL, 0 },
1194 /* 0xc8 */ { NULL, NULL, 0 },
1195 /* 0xc9 */ { NULL, NULL, 0 },
1196 /* 0xca */ { NULL, NULL, 0 },
1197 /* 0xcb */ { NULL, NULL, 0 },
1198 /* 0xcc */ { NULL, NULL, 0 },
1199 /* 0xcd */ { NULL, NULL, 0 },
1200 /* 0xce */ { NULL, NULL, 0 },
1201 /* 0xcf */ { NULL, NULL, 0 },
1202 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1203 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1204 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1205 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1206 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1207 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1208 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1209 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1210 /* 0xd8 */ { NULL, NULL, 0 },
1211 /* 0xd9 */ { NULL, NULL, 0 },
1212 /* 0xda */ { NULL, NULL, 0 },
1213 /* 0xdb */ { NULL, NULL, 0 },
1214 /* 0xdc */ { NULL, NULL, 0 },
1215 /* 0xdd */ { NULL, NULL, 0 },
1216 /* 0xde */ { NULL, NULL, 0 },
1217 /* 0xdf */ { NULL, NULL, 0 },
1218 /* 0xe0 */ { NULL, NULL, 0 },
1219 /* 0xe1 */ { NULL, NULL, 0 },
1220 /* 0xe2 */ { NULL, NULL, 0 },
1221 /* 0xe3 */ { NULL, NULL, 0 },
1222 /* 0xe4 */ { NULL, NULL, 0 },
1223 /* 0xe5 */ { NULL, NULL, 0 },
1224 /* 0xe6 */ { NULL, NULL, 0 },
1225 /* 0xe7 */ { NULL, NULL, 0 },
1226 /* 0xe8 */ { NULL, NULL, 0 },
1227 /* 0xe9 */ { NULL, NULL, 0 },
1228 /* 0xea */ { NULL, NULL, 0 },
1229 /* 0xeb */ { NULL, NULL, 0 },
1230 /* 0xec */ { NULL, NULL, 0 },
1231 /* 0xed */ { NULL, NULL, 0 },
1232 /* 0xee */ { NULL, NULL, 0 },
1233 /* 0xef */ { NULL, NULL, 0 },
1234 /* 0xf0 */ { NULL, NULL, 0 },
1235 /* 0xf1 */ { NULL, NULL, 0 },
1236 /* 0xf2 */ { NULL, NULL, 0 },
1237 /* 0xf3 */ { NULL, NULL, 0 },
1238 /* 0xf4 */ { NULL, NULL, 0 },
1239 /* 0xf5 */ { NULL, NULL, 0 },
1240 /* 0xf6 */ { NULL, NULL, 0 },
1241 /* 0xf7 */ { NULL, NULL, 0 },
1242 /* 0xf8 */ { NULL, NULL, 0 },
1243 /* 0xf9 */ { NULL, NULL, 0 },
1244 /* 0xfa */ { NULL, NULL, 0 },
1245 /* 0xfb */ { NULL, NULL, 0 },
1246 /* 0xfc */ { NULL, NULL, 0 },
1247 /* 0xfd */ { NULL, NULL, 0 },
1248 /* 0xfe */ { NULL, NULL, 0 },
1249 /* 0xff */ { NULL, NULL, 0 }
1253 /*******************************************************************
1254 allocate and initialize a reply packet
1255 ********************************************************************/
1257 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1258 const char *inbuf, char **outbuf, uint8_t num_words,
1259 uint32_t num_bytes)
1262 * Protect against integer wrap
1264 if ((num_bytes > 0xffffff)
1265 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1266 char *msg;
1267 if (asprintf(&msg, "num_bytes too large: %u",
1268 (unsigned)num_bytes) == -1) {
1269 msg = discard_const_p(char, "num_bytes too large");
1271 smb_panic(msg);
1274 *outbuf = talloc_array(mem_ctx, char,
1275 smb_size + num_words*2 + num_bytes);
1276 if (*outbuf == NULL) {
1277 return false;
1280 construct_reply_common(req, inbuf, *outbuf);
1281 srv_set_message(*outbuf, num_words, num_bytes, false);
1283 * Zero out the word area, the caller has to take care of the bcc area
1284 * himself
1286 if (num_words != 0) {
1287 memset(*outbuf + smb_vwv0, 0, num_words*2);
1290 return true;
1293 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1295 char *outbuf;
1296 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1297 num_bytes)) {
1298 smb_panic("could not allocate output buffer\n");
1300 req->outbuf = (uint8_t *)outbuf;
1304 /*******************************************************************
1305 Dump a packet to a file.
1306 ********************************************************************/
1308 static void smb_dump(const char *name, int type, const char *data)
1310 size_t len;
1311 int fd, i;
1312 char *fname = NULL;
1313 if (DEBUGLEVEL < 50) {
1314 return;
1317 len = smb_len_tcp(data)+4;
1318 for (i=1;i<100;i++) {
1319 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1320 type ? "req" : "resp") == -1) {
1321 return;
1323 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1324 if (fd != -1 || errno != EEXIST) break;
1326 if (fd != -1) {
1327 ssize_t ret = write(fd, data, len);
1328 if (ret != len)
1329 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1330 close(fd);
1331 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1333 SAFE_FREE(fname);
1336 /****************************************************************************
1337 Prepare everything for calling the actual request function, and potentially
1338 call the request function via the "new" interface.
1340 Return False if the "legacy" function needs to be called, everything is
1341 prepared.
1343 Return True if we're done.
1345 I know this API sucks, but it is the one with the least code change I could
1346 find.
1347 ****************************************************************************/
1349 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1351 int flags;
1352 uint16 session_tag;
1353 connection_struct *conn = NULL;
1354 struct smbd_server_connection *sconn = req->sconn;
1356 errno = 0;
1358 if (smb_messages[type].fn == NULL) {
1359 DEBUG(0,("Unknown message type %d!\n",type));
1360 smb_dump("Unknown", 1, (const char *)req->inbuf);
1361 reply_unknown_new(req, type);
1362 return NULL;
1365 flags = smb_messages[type].flags;
1367 /* In share mode security we must ignore the vuid. */
1368 session_tag = req->vuid;
1369 conn = req->conn;
1371 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1372 (int)sys_getpid(), (unsigned long)conn));
1374 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1376 /* Ensure this value is replaced in the incoming packet. */
1377 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1380 * Ensure the correct username is in current_user_info. This is a
1381 * really ugly bugfix for problems with multiple session_setup_and_X's
1382 * being done and allowing %U and %G substitutions to work correctly.
1383 * There is a reason this code is done here, don't move it unless you
1384 * know what you're doing... :-).
1385 * JRA.
1388 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1389 user_struct *vuser = NULL;
1391 sconn->smb1.sessions.last_session_tag = session_tag;
1392 if(session_tag != UID_FIELD_INVALID) {
1393 vuser = get_valid_user_struct(sconn, session_tag);
1394 if (vuser) {
1395 set_current_user_info(
1396 vuser->session_info->unix_info->sanitized_username,
1397 vuser->session_info->unix_info->unix_name,
1398 vuser->session_info->info->domain_name);
1403 /* Does this call need to be run as the connected user? */
1404 if (flags & AS_USER) {
1406 /* Does this call need a valid tree connection? */
1407 if (!conn) {
1409 * Amazingly, the error code depends on the command
1410 * (from Samba4).
1412 if (type == SMBntcreateX) {
1413 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1414 } else {
1415 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1417 return NULL;
1420 if (!change_to_user(conn,session_tag)) {
1421 DEBUG(0, ("Error: Could not change to user. Removing "
1422 "deferred open, mid=%llu.\n",
1423 (unsigned long long)req->mid));
1424 reply_force_doserror(req, ERRSRV, ERRbaduid);
1425 return conn;
1428 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1430 /* Does it need write permission? */
1431 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1432 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1433 return conn;
1436 /* IPC services are limited */
1437 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1438 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1439 return conn;
1441 } else {
1442 /* This call needs to be run as root */
1443 change_to_root_user();
1446 /* load service specific parameters */
1447 if (conn) {
1448 if (req->encrypted) {
1449 conn->encrypted_tid = true;
1450 /* encrypted required from now on. */
1451 conn->encrypt_level = Required;
1452 } else if (ENCRYPTION_REQUIRED(conn)) {
1453 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1454 exit_server_cleanly("encryption required "
1455 "on connection");
1456 return conn;
1460 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1461 (flags & (AS_USER|DO_CHDIR)
1462 ?True:False))) {
1463 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1464 return conn;
1466 conn->num_smb_operations++;
1470 * Does this protocol need to be run as guest? (Only archane
1471 * messenger service requests have this...)
1473 if (flags & AS_GUEST) {
1474 char *raddr;
1475 bool ok;
1477 if (!change_to_guest()) {
1478 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1479 return conn;
1482 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1483 talloc_tos());
1484 if (raddr == NULL) {
1485 reply_nterror(req, NT_STATUS_NO_MEMORY);
1486 return conn;
1490 * Haven't we checked this in smbd_process already???
1493 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1494 sconn->remote_hostname, raddr);
1495 TALLOC_FREE(raddr);
1497 if (!ok) {
1498 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1499 return conn;
1503 smb_messages[type].fn(req);
1504 return req->conn;
1507 /****************************************************************************
1508 Construct a reply to the incoming packet.
1509 ****************************************************************************/
1511 static void construct_reply(struct smbd_server_connection *sconn,
1512 char *inbuf, int size, size_t unread_bytes,
1513 uint32_t seqnum, bool encrypted,
1514 struct smb_perfcount_data *deferred_pcd)
1516 connection_struct *conn;
1517 struct smb_request *req;
1519 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1520 smb_panic("could not allocate smb_request");
1523 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1524 encrypted, seqnum)) {
1525 exit_server_cleanly("Invalid SMB request");
1528 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1530 /* we popped this message off the queue - keep original perf data */
1531 if (deferred_pcd)
1532 req->pcd = *deferred_pcd;
1533 else {
1534 SMB_PERFCOUNT_START(&req->pcd);
1535 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1536 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1539 conn = switch_message(req->cmd, req);
1541 if (req->done) {
1542 TALLOC_FREE(req);
1543 return;
1546 if (req->outbuf == NULL) {
1547 return;
1550 if (CVAL(req->outbuf,0) == 0) {
1551 show_msg((char *)req->outbuf);
1554 if (!srv_send_smb(req->sconn,
1555 (char *)req->outbuf,
1556 true, req->seqnum+1,
1557 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1558 &req->pcd)) {
1559 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1562 TALLOC_FREE(req);
1564 return;
1567 static void construct_reply_chain(struct smbd_server_connection *sconn,
1568 char *inbuf, int size, uint32_t seqnum,
1569 bool encrypted,
1570 struct smb_perfcount_data *deferred_pcd)
1572 struct connection_struct *conn = NULL;
1573 struct smb_request **reqs = NULL;
1574 struct smb_request *req, *first_req, *last_req;
1575 unsigned i, num_reqs;
1576 NTSTATUS status;
1577 bool ok;
1579 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1580 seqnum, &reqs, &num_reqs);
1581 if (!ok) {
1582 status = NT_STATUS_INVALID_PARAMETER;
1583 goto error;
1586 for (i=0; i<num_reqs; i++) {
1587 req = reqs[i];
1589 if (i > 0) {
1591 * Get the session and tree ids and chain fsp
1592 * from the previous request into the current
1593 * one
1595 struct smb_request *prev_req = reqs[i-1];
1596 const uint8_t *prev_outbuf = prev_req->outbuf;
1598 req->vuid = SVAL(prev_outbuf, smb_uid);
1599 req->tid = SVAL(prev_outbuf, smb_tid);
1600 req->conn = conn_find(req->sconn, req->tid);
1601 req->chain_fsp = prev_req->chain_fsp;
1603 req->inbuf = (uint8_t *)inbuf;
1604 conn = switch_message(req->cmd, req);
1606 if (req->outbuf == NULL) {
1607 if (open_was_deferred(req->sconn, req->mid)) {
1608 TALLOC_FREE(reqs);
1609 return;
1611 status = NT_STATUS_INTERNAL_ERROR;
1612 goto error;
1614 if (IVAL(req->outbuf, smb_rcls) != 0) {
1615 break;
1619 first_req = reqs[0];
1620 last_req = req;
1622 if (i == 0) {
1624 * The first request already gave an error, no need to
1625 * do any splicing
1627 goto shipit;
1630 for (i=1; i<next_index; i++) {
1631 req = reqs[i];
1633 ok = smb_splice_chain(&first_req->outbuf, req->outbuf);
1634 if (!ok) {
1635 status = NT_STATUS_INTERNAL_ERROR;
1636 goto error;
1638 if (req == last_req) {
1639 break;
1643 SSVAL(first_req->outbuf, smb_uid, SVAL(last_req->outbuf, smb_uid));
1644 SSVAL(first_req->outbuf, smb_tid, SVAL(last_req->outbuf, smb_tid));
1647 * This scary statement intends to set the
1648 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1649 * to the value last_req->outbuf carries
1651 SSVAL(first_req->outbuf, smb_flg2,
1652 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1653 |(SVAL(last_req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1656 * Transfer the error codes from the subrequest to the main one
1658 SSVAL(first_req->outbuf, smb_rcls, SVAL(last_req->outbuf, smb_rcls));
1659 SSVAL(first_req->outbuf, smb_err, SVAL(last_req->outbuf, smb_err));
1661 goto shipit;
1663 shipit:
1664 _smb_setlen_large(first_req->outbuf,
1665 talloc_get_size(first_req->outbuf) - 4);
1667 if (!srv_send_smb(first_req->sconn,
1668 (char *)first_req->outbuf,
1669 true, first_req->seqnum+1,
1670 IS_CONN_ENCRYPTED(conn)||first_req->encrypted,
1671 &first_req->pcd)) {
1672 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1673 "failed.");
1675 TALLOC_FREE(reqs);
1676 return;
1678 error:
1680 char errbuf[smb_size];
1681 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1682 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1683 NULL)) {
1684 exit_server_cleanly("construct_reply_chain: "
1685 "srv_send_smb failed.");
1688 TALLOC_FREE(reqs);
1691 /****************************************************************************
1692 Process an smb from the client
1693 ****************************************************************************/
1694 static void process_smb(struct smbd_server_connection *sconn,
1695 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1696 uint32_t seqnum, bool encrypted,
1697 struct smb_perfcount_data *deferred_pcd)
1699 int msg_type = CVAL(inbuf,0);
1701 DO_PROFILE_INC(smb_count);
1703 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1704 smb_len(inbuf) ) );
1705 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1706 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1708 if (msg_type != NBSSmessage) {
1710 * NetBIOS session request, keepalive, etc.
1712 reply_special(sconn, (char *)inbuf, nread);
1713 goto done;
1716 if (sconn->using_smb2) {
1717 /* At this point we're not really using smb2,
1718 * we make the decision here.. */
1719 if (smbd_is_smb2_header(inbuf, nread)) {
1720 smbd_smb2_first_negprot(sconn, inbuf, nread);
1721 return;
1722 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1723 && CVAL(inbuf, smb_com) != 0x72) {
1724 /* This is a non-negprot SMB1 packet.
1725 Disable SMB2 from now on. */
1726 sconn->using_smb2 = false;
1730 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1731 * so subtract 4 from it. */
1732 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1733 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1734 smb_len(inbuf)));
1736 /* special magic for immediate exit */
1737 if ((nread == 9) &&
1738 (IVAL(inbuf, 4) == 0x74697865) &&
1739 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1740 uint8_t exitcode = CVAL(inbuf, 8);
1741 DEBUG(1, ("Exiting immediately with code %d\n",
1742 (int)exitcode));
1743 exit(exitcode);
1746 exit_server_cleanly("Non-SMB packet");
1749 show_msg((char *)inbuf);
1751 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1752 construct_reply_chain(sconn, (char *)inbuf, nread,
1753 seqnum, encrypted, deferred_pcd);
1754 } else {
1755 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1756 seqnum, encrypted, deferred_pcd);
1759 sconn->trans_num++;
1761 done:
1762 sconn->num_requests++;
1764 /* The timeout_processing function isn't run nearly
1765 often enough to implement 'max log size' without
1766 overrunning the size of the file by many megabytes.
1767 This is especially true if we are running at debug
1768 level 10. Checking every 50 SMBs is a nice
1769 tradeoff of performance vs log file size overrun. */
1771 if ((sconn->num_requests % 50) == 0 &&
1772 need_to_check_log_size()) {
1773 change_to_root_user();
1774 check_log_size();
1778 /****************************************************************************
1779 Return a string containing the function name of a SMB command.
1780 ****************************************************************************/
1782 const char *smb_fn_name(int type)
1784 const char *unknown_name = "SMBunknown";
1786 if (smb_messages[type].name == NULL)
1787 return(unknown_name);
1789 return(smb_messages[type].name);
1792 /****************************************************************************
1793 Helper functions for contruct_reply.
1794 ****************************************************************************/
1796 void add_to_common_flags2(uint32 v)
1798 common_flags2 |= v;
1801 void remove_from_common_flags2(uint32 v)
1803 common_flags2 &= ~v;
1806 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1807 char *outbuf)
1809 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1810 uint16_t out_flags2 = common_flags2;
1812 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1813 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1814 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1816 srv_set_message(outbuf,0,0,false);
1818 SCVAL(outbuf, smb_com, req->cmd);
1819 SIVAL(outbuf,smb_rcls,0);
1820 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1821 SSVAL(outbuf,smb_flg2, out_flags2);
1822 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1823 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1825 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1826 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1827 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1828 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1831 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1833 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1837 * How many bytes have we already accumulated up to the current wct field
1838 * offset?
1841 size_t req_wct_ofs(struct smb_request *req)
1843 size_t buf_size;
1845 if (req->chain_outbuf == NULL) {
1846 return smb_wct - 4;
1848 buf_size = talloc_get_size(req->chain_outbuf);
1849 if ((buf_size % 4) != 0) {
1850 buf_size += (4 - (buf_size % 4));
1852 return buf_size - 4;
1856 * @brief Find the smb_cmd offset of the last command pushed
1857 * @param[in] buf The buffer we're building up
1858 * @retval Where can we put our next andx cmd?
1860 * While chaining requests, the "next" request we're looking at needs to put
1861 * its SMB_Command before the data the previous request already built up added
1862 * to the chain. Find the offset to the place where we have to put our cmd.
1865 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1867 uint8_t cmd;
1868 size_t ofs;
1870 cmd = CVAL(buf, smb_com);
1872 if (!is_andx_req(cmd)) {
1873 return false;
1876 ofs = smb_vwv0;
1878 while (CVAL(buf, ofs) != 0xff) {
1880 if (!is_andx_req(CVAL(buf, ofs))) {
1881 return false;
1885 * ofs is from start of smb header, so add the 4 length
1886 * bytes. The next cmd is right after the wct field.
1888 ofs = SVAL(buf, ofs+2) + 4 + 1;
1890 if (ofs+4 >= talloc_get_size(buf)) {
1891 return false;
1895 *pofs = ofs;
1896 return true;
1900 * @brief Do the smb chaining at a buffer level
1901 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1902 * @param[in] andx_buf Buffer to be appended
1905 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1907 uint8_t smb_command = CVAL(andx_buf, smb_com);
1908 uint8_t wct = CVAL(andx_buf, smb_wct);
1909 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1910 uint32_t num_bytes = smb_buflen(andx_buf);
1911 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1913 uint8_t *outbuf;
1914 size_t old_size, new_size;
1915 size_t ofs;
1916 size_t chain_padding = 0;
1917 size_t andx_cmd_ofs;
1920 old_size = talloc_get_size(*poutbuf);
1922 if ((old_size % 4) != 0) {
1924 * Align the wct field of subsequent requests to a 4-byte
1925 * boundary
1927 chain_padding = 4 - (old_size % 4);
1931 * After the old request comes the new wct field (1 byte), the vwv's
1932 * and the num_bytes field.
1935 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1936 new_size += num_bytes;
1938 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1939 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1940 (unsigned)new_size));
1941 return false;
1944 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1945 if (outbuf == NULL) {
1946 DEBUG(0, ("talloc failed\n"));
1947 return false;
1949 *poutbuf = outbuf;
1951 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1952 DEBUG(1, ("invalid command chain\n"));
1953 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
1954 return false;
1957 if (chain_padding != 0) {
1958 memset(outbuf + old_size, 0, chain_padding);
1959 old_size += chain_padding;
1962 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1963 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1965 ofs = old_size;
1968 * Push the chained request:
1970 * wct field
1973 SCVAL(outbuf, ofs, wct);
1974 ofs += 1;
1977 * vwv array
1980 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1983 * HACK ALERT
1985 * Read&X has an offset into its data buffer at
1986 * vwv[6]. reply_read_andx has no idea anymore that it's
1987 * running from within a chain, so we have to fix up the
1988 * offset here.
1990 * Although it looks disgusting at this place, I want to keep
1991 * it here. The alternative would be to push knowledge about
1992 * the andx chain down into read&x again.
1995 if (smb_command == SMBreadX) {
1996 uint8_t *bytes_addr;
1998 if (wct < 7) {
2000 * Invalid read&x response
2002 return false;
2005 bytes_addr = outbuf + ofs /* vwv start */
2006 + sizeof(uint16_t) * wct /* vwv array */
2007 + sizeof(uint16_t); /* bcc */
2009 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2010 bytes_addr - outbuf - 4);
2013 ofs += sizeof(uint16_t) * wct;
2016 * bcc (byte count)
2019 SSVAL(outbuf, ofs, num_bytes);
2020 ofs += sizeof(uint16_t);
2023 * The bytes field
2026 memcpy(outbuf + ofs, bytes, num_bytes);
2028 return true;
2031 bool smb1_is_chain(const uint8_t *buf)
2033 uint8_t cmd, wct, andx_cmd;
2035 cmd = CVAL(buf, smb_com);
2036 if (!is_andx_req(cmd)) {
2037 return false;
2039 wct = CVAL(buf, smb_wct);
2040 if (wct < 2) {
2041 return false;
2043 andx_cmd = CVAL(buf, smb_vwv);
2044 return (andx_cmd != 0xFF);
2047 bool smb1_walk_chain(const uint8_t *buf,
2048 bool (*fn)(uint8_t cmd,
2049 uint8_t wct, const uint16_t *vwv,
2050 uint16_t num_bytes, const uint8_t *bytes,
2051 void *private_data),
2052 void *private_data)
2054 size_t smblen = smb_len(buf);
2055 const char *smb_buf = smb_base(buf);
2056 uint8_t cmd, chain_cmd;
2057 uint8_t wct;
2058 const uint16_t *vwv;
2059 uint16_t num_bytes;
2060 const uint8_t *bytes;
2062 cmd = CVAL(buf, smb_com);
2063 wct = CVAL(buf, smb_wct);
2064 vwv = (const uint16_t *)(buf + smb_vwv);
2065 num_bytes = smb_buflen(buf);
2066 bytes = (uint8_t *)smb_buf_const(buf);
2068 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2069 return false;
2072 if (!is_andx_req(cmd)) {
2073 return true;
2075 if (wct < 2) {
2076 return false;
2079 chain_cmd = CVAL(vwv, 0);
2081 while (chain_cmd != 0xff) {
2082 uint32_t chain_offset; /* uint32_t to avoid overflow */
2083 size_t length_needed;
2084 ptrdiff_t vwv_offset;
2086 chain_offset = SVAL(vwv+1, 0);
2089 * Check if the client tries to fool us. The chain
2090 * offset needs to point beyond the current request in
2091 * the chain, it needs to strictly grow. Otherwise we
2092 * might be tricked into an endless loop always
2093 * processing the same request over and over again. We
2094 * used to assume that vwv and the byte buffer array
2095 * in a chain are always attached, but OS/2 the
2096 * Write&X/Read&X chain puts the Read&X vwv array
2097 * right behind the Write&X vwv chain. The Write&X bcc
2098 * array is put behind the Read&X vwv array. So now we
2099 * check whether the chain offset points strictly
2100 * behind the previous vwv array. req->buf points
2101 * right after the vwv array of the previous
2102 * request. See
2103 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2104 * more information.
2107 vwv_offset = ((const char *)vwv - smb_buf);
2108 if (chain_offset <= vwv_offset) {
2109 return false;
2113 * Next check: Make sure the chain offset does not
2114 * point beyond the overall smb request length.
2117 length_needed = chain_offset+1; /* wct */
2118 if (length_needed > smblen) {
2119 return false;
2123 * Now comes the pointer magic. Goal here is to set up
2124 * vwv and buf correctly again. The chain offset (the
2125 * former vwv[1]) points at the new wct field.
2128 wct = CVAL(smb_buf, chain_offset);
2130 if (is_andx_req(chain_cmd) && (wct < 2)) {
2131 return false;
2135 * Next consistency check: Make the new vwv array fits
2136 * in the overall smb request.
2139 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2140 if (length_needed > smblen) {
2141 return false;
2143 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2146 * Now grab the new byte buffer....
2149 num_bytes = SVAL(vwv+wct, 0);
2152 * .. and check that it fits.
2155 length_needed += num_bytes;
2156 if (length_needed > smblen) {
2157 return false;
2159 bytes = (const uint8_t *)(vwv+wct+1);
2161 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2162 return false;
2165 if (!is_andx_req(chain_cmd)) {
2166 return true;
2168 chain_cmd = CVAL(vwv, 0);
2170 return true;
2173 static bool smb1_chain_length_cb(uint8_t cmd,
2174 uint8_t wct, const uint16_t *vwv,
2175 uint16_t num_bytes, const uint8_t *bytes,
2176 void *private_data)
2178 unsigned *count = (unsigned *)private_data;
2179 *count += 1;
2180 return true;
2183 unsigned smb1_chain_length(const uint8_t *buf)
2185 unsigned count = 0;
2187 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2188 return 0;
2190 return count;
2193 struct smb1_parse_chain_state {
2194 TALLOC_CTX *mem_ctx;
2195 const uint8_t *buf;
2196 struct smbd_server_connection *sconn;
2197 bool encrypted;
2198 uint32_t seqnum;
2200 struct smb_request **reqs;
2201 unsigned num_reqs;
2204 static bool smb1_parse_chain_cb(uint8_t cmd,
2205 uint8_t wct, const uint16_t *vwv,
2206 uint16_t num_bytes, const uint8_t *bytes,
2207 void *private_data)
2209 struct smb1_parse_chain_state *state =
2210 (struct smb1_parse_chain_state *)private_data;
2211 struct smb_request **reqs;
2212 struct smb_request *req;
2213 bool ok;
2215 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2216 struct smb_request *, state->num_reqs+1);
2217 if (reqs == NULL) {
2218 return false;
2220 state->reqs = reqs;
2222 req = talloc(reqs, struct smb_request);
2223 if (req == NULL) {
2224 return false;
2227 ok = init_smb_request(req, state->sconn, state->buf, 0,
2228 state->encrypted, state->seqnum);
2229 if (!ok) {
2230 return false;
2232 req->cmd = cmd;
2233 req->wct = wct;
2234 req->vwv = vwv;
2235 req->buflen = num_bytes;
2236 req->buf = bytes;
2238 reqs[state->num_reqs] = req;
2239 state->num_reqs += 1;
2240 return true;
2243 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2244 struct smbd_server_connection *sconn,
2245 bool encrypted, uint32_t seqnum,
2246 struct smb_request ***reqs, unsigned *num_reqs)
2248 struct smb1_parse_chain_state state;
2250 state.mem_ctx = mem_ctx;
2251 state.buf = buf;
2252 state.sconn = sconn;
2253 state.encrypted = encrypted;
2254 state.seqnum = seqnum;
2255 state.reqs = NULL;
2256 state.num_reqs = 0;
2258 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2259 TALLOC_FREE(state.reqs);
2260 return false;
2262 *reqs = state.reqs;
2263 *num_reqs = state.num_reqs;
2264 return true;
2267 /****************************************************************************
2268 Check if services need reloading.
2269 ****************************************************************************/
2271 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2274 if (last_smb_conf_reload_time == 0) {
2275 last_smb_conf_reload_time = t;
2278 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2279 reload_services(sconn, conn_snum_used, true);
2280 last_smb_conf_reload_time = t;
2284 static bool fd_is_readable(int fd)
2286 int ret, revents;
2288 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2290 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2294 static void smbd_server_connection_write_handler(
2295 struct smbd_server_connection *sconn)
2297 /* TODO: make write nonblocking */
2300 static void smbd_server_connection_read_handler(
2301 struct smbd_server_connection *sconn, int fd)
2303 uint8_t *inbuf = NULL;
2304 size_t inbuf_len = 0;
2305 size_t unread_bytes = 0;
2306 bool encrypted = false;
2307 TALLOC_CTX *mem_ctx = talloc_tos();
2308 NTSTATUS status;
2309 uint32_t seqnum;
2311 bool from_client;
2313 if (lp_async_smb_echo_handler()
2314 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2316 * This is the super-ugly hack to prefer the packets
2317 * forwarded by the echo handler over the ones by the
2318 * client directly
2320 fd = sconn->smb1.echo_handler.trusted_fd;
2323 from_client = (sconn->sock == fd);
2325 if (from_client) {
2326 smbd_lock_socket(sconn);
2328 if (!fd_is_readable(fd)) {
2329 DEBUG(10,("the echo listener was faster\n"));
2330 smbd_unlock_socket(sconn);
2331 return;
2335 /* TODO: make this completely nonblocking */
2336 status = receive_smb_talloc(mem_ctx, sconn, fd,
2337 (char **)(void *)&inbuf,
2338 0, /* timeout */
2339 &unread_bytes,
2340 &encrypted,
2341 &inbuf_len, &seqnum,
2342 false /* trusted channel */);
2344 if (from_client) {
2345 smbd_unlock_socket(sconn);
2348 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2349 goto process;
2351 if (NT_STATUS_IS_ERR(status)) {
2352 exit_server_cleanly("failed to receive smb request");
2354 if (!NT_STATUS_IS_OK(status)) {
2355 return;
2358 process:
2359 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2360 seqnum, encrypted, NULL);
2363 static void smbd_server_connection_handler(struct event_context *ev,
2364 struct fd_event *fde,
2365 uint16_t flags,
2366 void *private_data)
2368 struct smbd_server_connection *conn = talloc_get_type(private_data,
2369 struct smbd_server_connection);
2371 if (flags & EVENT_FD_WRITE) {
2372 smbd_server_connection_write_handler(conn);
2373 return;
2375 if (flags & EVENT_FD_READ) {
2376 smbd_server_connection_read_handler(conn, conn->sock);
2377 return;
2381 static void smbd_server_echo_handler(struct event_context *ev,
2382 struct fd_event *fde,
2383 uint16_t flags,
2384 void *private_data)
2386 struct smbd_server_connection *conn = talloc_get_type(private_data,
2387 struct smbd_server_connection);
2389 if (flags & EVENT_FD_WRITE) {
2390 smbd_server_connection_write_handler(conn);
2391 return;
2393 if (flags & EVENT_FD_READ) {
2394 smbd_server_connection_read_handler(
2395 conn, conn->smb1.echo_handler.trusted_fd);
2396 return;
2400 #ifdef CLUSTER_SUPPORT
2401 /****************************************************************************
2402 received when we should release a specific IP
2403 ****************************************************************************/
2404 static void release_ip(const char *ip, void *priv)
2406 const char *addr = (const char *)priv;
2407 const char *p = addr;
2409 if (strncmp("::ffff:", addr, 7) == 0) {
2410 p = addr + 7;
2413 DEBUG(10, ("Got release IP message for %s, "
2414 "our address is %s\n", ip, p));
2416 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2417 /* we can't afford to do a clean exit - that involves
2418 database writes, which would potentially mean we
2419 are still running after the failover has finished -
2420 we have to get rid of this process ID straight
2421 away */
2422 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2423 ip));
2424 /* note we must exit with non-zero status so the unclean handler gets
2425 called in the parent, so that the brl database is tickled */
2426 _exit(1);
2430 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2431 struct sockaddr_storage *client)
2433 socklen_t length;
2434 length = sizeof(*server);
2435 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2436 return -1;
2438 length = sizeof(*client);
2439 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2440 return -1;
2442 return 0;
2444 #endif
2447 * Send keepalive packets to our client
2449 static bool keepalive_fn(const struct timeval *now, void *private_data)
2451 struct smbd_server_connection *sconn = talloc_get_type_abort(
2452 private_data, struct smbd_server_connection);
2453 bool ret;
2455 if (sconn->using_smb2) {
2456 /* Don't do keepalives on an SMB2 connection. */
2457 return false;
2460 smbd_lock_socket(sconn);
2461 ret = send_keepalive(sconn->sock);
2462 smbd_unlock_socket(sconn);
2464 if (!ret) {
2465 char addr[INET6_ADDRSTRLEN];
2467 * Try and give an error message saying what
2468 * client failed.
2470 DEBUG(0, ("send_keepalive failed for client %s. "
2471 "Error %s - exiting\n",
2472 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2473 strerror(errno)));
2474 return False;
2476 return True;
2480 * Do the recurring check if we're idle
2482 static bool deadtime_fn(const struct timeval *now, void *private_data)
2484 struct smbd_server_connection *sconn =
2485 (struct smbd_server_connection *)private_data;
2487 if ((conn_num_open(sconn) == 0)
2488 || (conn_idle_all(sconn, now->tv_sec))) {
2489 DEBUG( 2, ( "Closing idle connection\n" ) );
2490 messaging_send(sconn->msg_ctx,
2491 messaging_server_id(sconn->msg_ctx),
2492 MSG_SHUTDOWN, &data_blob_null);
2493 return False;
2496 return True;
2500 * Do the recurring log file and smb.conf reload checks.
2503 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2505 struct smbd_server_connection *sconn = talloc_get_type_abort(
2506 private_data, struct smbd_server_connection);
2508 DEBUG(5, ("housekeeping\n"));
2510 change_to_root_user();
2512 /* update printer queue caches if necessary */
2513 update_monitored_printq_cache(sconn->msg_ctx);
2515 /* check if we need to reload services */
2516 check_reload(sconn, time_mono(NULL));
2518 /* Change machine password if neccessary. */
2519 attempt_machine_password_change();
2522 * Force a log file check.
2524 force_check_log_size();
2525 check_log_size();
2526 return true;
2530 * Read an smb packet in the echo handler child, giving the parent
2531 * smbd one second to react once the socket becomes readable.
2534 struct smbd_echo_read_state {
2535 struct tevent_context *ev;
2536 struct smbd_server_connection *sconn;
2538 char *buf;
2539 size_t buflen;
2540 uint32_t seqnum;
2543 static void smbd_echo_read_readable(struct tevent_req *subreq);
2544 static void smbd_echo_read_waited(struct tevent_req *subreq);
2546 static struct tevent_req *smbd_echo_read_send(
2547 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2548 struct smbd_server_connection *sconn)
2550 struct tevent_req *req, *subreq;
2551 struct smbd_echo_read_state *state;
2553 req = tevent_req_create(mem_ctx, &state,
2554 struct smbd_echo_read_state);
2555 if (req == NULL) {
2556 return NULL;
2558 state->ev = ev;
2559 state->sconn = sconn;
2561 subreq = wait_for_read_send(state, ev, sconn->sock);
2562 if (tevent_req_nomem(subreq, req)) {
2563 return tevent_req_post(req, ev);
2565 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2566 return req;
2569 static void smbd_echo_read_readable(struct tevent_req *subreq)
2571 struct tevent_req *req = tevent_req_callback_data(
2572 subreq, struct tevent_req);
2573 struct smbd_echo_read_state *state = tevent_req_data(
2574 req, struct smbd_echo_read_state);
2575 bool ok;
2576 int err;
2578 ok = wait_for_read_recv(subreq, &err);
2579 TALLOC_FREE(subreq);
2580 if (!ok) {
2581 tevent_req_nterror(req, map_nt_error_from_unix(err));
2582 return;
2586 * Give the parent smbd one second to step in
2589 subreq = tevent_wakeup_send(
2590 state, state->ev, timeval_current_ofs(1, 0));
2591 if (tevent_req_nomem(subreq, req)) {
2592 return;
2594 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2597 static void smbd_echo_read_waited(struct tevent_req *subreq)
2599 struct tevent_req *req = tevent_req_callback_data(
2600 subreq, struct tevent_req);
2601 struct smbd_echo_read_state *state = tevent_req_data(
2602 req, struct smbd_echo_read_state);
2603 struct smbd_server_connection *sconn = state->sconn;
2604 bool ok;
2605 NTSTATUS status;
2606 size_t unread = 0;
2607 bool encrypted;
2609 ok = tevent_wakeup_recv(subreq);
2610 TALLOC_FREE(subreq);
2611 if (!ok) {
2612 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2613 return;
2616 ok = smbd_lock_socket_internal(sconn);
2617 if (!ok) {
2618 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2619 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2620 return;
2623 if (!fd_is_readable(sconn->sock)) {
2624 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2625 (int)sys_getpid()));
2627 ok = smbd_unlock_socket_internal(sconn);
2628 if (!ok) {
2629 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2630 DEBUG(1, ("%s: failed to unlock socket\n",
2631 __location__));
2632 return;
2635 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2636 if (tevent_req_nomem(subreq, req)) {
2637 return;
2639 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2640 return;
2643 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2644 0 /* timeout */,
2645 &unread,
2646 &encrypted,
2647 &state->buflen,
2648 &state->seqnum,
2649 false /* trusted_channel*/);
2651 if (tevent_req_nterror(req, status)) {
2652 tevent_req_nterror(req, status);
2653 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2654 (int)sys_getpid(), nt_errstr(status)));
2655 return;
2658 ok = smbd_unlock_socket_internal(sconn);
2659 if (!ok) {
2660 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2661 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2662 return;
2664 tevent_req_done(req);
2667 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2668 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2670 struct smbd_echo_read_state *state = tevent_req_data(
2671 req, struct smbd_echo_read_state);
2672 NTSTATUS status;
2674 if (tevent_req_is_nterror(req, &status)) {
2675 return status;
2677 *pbuf = talloc_move(mem_ctx, &state->buf);
2678 *pbuflen = state->buflen;
2679 *pseqnum = state->seqnum;
2680 return NT_STATUS_OK;
2683 struct smbd_echo_state {
2684 struct tevent_context *ev;
2685 struct iovec *pending;
2686 struct smbd_server_connection *sconn;
2687 int parent_pipe;
2689 struct tevent_fd *parent_fde;
2691 struct tevent_req *write_req;
2694 static void smbd_echo_writer_done(struct tevent_req *req);
2696 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2698 int num_pending;
2700 if (state->write_req != NULL) {
2701 return;
2704 num_pending = talloc_array_length(state->pending);
2705 if (num_pending == 0) {
2706 return;
2709 state->write_req = writev_send(state, state->ev, NULL,
2710 state->parent_pipe, false,
2711 state->pending, num_pending);
2712 if (state->write_req == NULL) {
2713 DEBUG(1, ("writev_send failed\n"));
2714 exit(1);
2717 talloc_steal(state->write_req, state->pending);
2718 state->pending = NULL;
2720 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2721 state);
2724 static void smbd_echo_writer_done(struct tevent_req *req)
2726 struct smbd_echo_state *state = tevent_req_callback_data(
2727 req, struct smbd_echo_state);
2728 ssize_t written;
2729 int err;
2731 written = writev_recv(req, &err);
2732 TALLOC_FREE(req);
2733 state->write_req = NULL;
2734 if (written == -1) {
2735 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2736 exit(1);
2738 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2739 smbd_echo_activate_writer(state);
2742 static bool smbd_echo_reply(struct smbd_echo_state *state,
2743 uint8_t *inbuf, size_t inbuf_len,
2744 uint32_t seqnum)
2746 struct smb_request req;
2747 uint16_t num_replies;
2748 char *outbuf;
2749 bool ok;
2751 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2752 DEBUG(10, ("Got netbios keepalive\n"));
2754 * Just swallow it
2756 return true;
2759 if (inbuf_len < smb_size) {
2760 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2761 return false;
2763 if (!valid_smb_header(state->sconn, inbuf)) {
2764 DEBUG(10, ("Got invalid SMB header\n"));
2765 return false;
2768 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2769 seqnum)) {
2770 return false;
2772 req.inbuf = inbuf;
2774 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2775 smb_messages[req.cmd].name
2776 ? smb_messages[req.cmd].name : "unknown"));
2778 if (req.cmd != SMBecho) {
2779 return false;
2781 if (req.wct < 1) {
2782 return false;
2785 num_replies = SVAL(req.vwv+0, 0);
2786 if (num_replies != 1) {
2787 /* Not a Windows "Hey, you're still there?" request */
2788 return false;
2791 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2792 1, req.buflen)) {
2793 DEBUG(10, ("create_outbuf failed\n"));
2794 return false;
2796 req.outbuf = (uint8_t *)outbuf;
2798 SSVAL(req.outbuf, smb_vwv0, num_replies);
2800 if (req.buflen > 0) {
2801 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2804 ok = srv_send_smb(req.sconn,
2805 (char *)outbuf,
2806 true, seqnum+1,
2807 false, &req.pcd);
2808 TALLOC_FREE(outbuf);
2809 if (!ok) {
2810 exit(1);
2813 return true;
2816 static void smbd_echo_exit(struct tevent_context *ev,
2817 struct tevent_fd *fde, uint16_t flags,
2818 void *private_data)
2820 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2821 exit(0);
2824 static void smbd_echo_got_packet(struct tevent_req *req);
2826 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2827 int parent_pipe)
2829 struct smbd_echo_state *state;
2830 struct tevent_req *read_req;
2832 state = talloc_zero(sconn, struct smbd_echo_state);
2833 if (state == NULL) {
2834 DEBUG(1, ("talloc failed\n"));
2835 return;
2837 state->sconn = sconn;
2838 state->parent_pipe = parent_pipe;
2839 state->ev = s3_tevent_context_init(state);
2840 if (state->ev == NULL) {
2841 DEBUG(1, ("tevent_context_init failed\n"));
2842 TALLOC_FREE(state);
2843 return;
2845 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2846 TEVENT_FD_READ, smbd_echo_exit,
2847 state);
2848 if (state->parent_fde == NULL) {
2849 DEBUG(1, ("tevent_add_fd failed\n"));
2850 TALLOC_FREE(state);
2851 return;
2854 read_req = smbd_echo_read_send(state, state->ev, sconn);
2855 if (read_req == NULL) {
2856 DEBUG(1, ("smbd_echo_read_send failed\n"));
2857 TALLOC_FREE(state);
2858 return;
2860 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2862 while (true) {
2863 if (tevent_loop_once(state->ev) == -1) {
2864 DEBUG(1, ("tevent_loop_once failed: %s\n",
2865 strerror(errno)));
2866 break;
2869 TALLOC_FREE(state);
2872 static void smbd_echo_got_packet(struct tevent_req *req)
2874 struct smbd_echo_state *state = tevent_req_callback_data(
2875 req, struct smbd_echo_state);
2876 NTSTATUS status;
2877 char *buf = NULL;
2878 size_t buflen = 0;
2879 uint32_t seqnum = 0;
2880 bool reply;
2882 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2883 TALLOC_FREE(req);
2884 if (!NT_STATUS_IS_OK(status)) {
2885 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2886 nt_errstr(status)));
2887 exit(1);
2890 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2891 if (!reply) {
2892 size_t num_pending;
2893 struct iovec *tmp;
2894 struct iovec *iov;
2896 num_pending = talloc_array_length(state->pending);
2897 tmp = talloc_realloc(state, state->pending, struct iovec,
2898 num_pending+1);
2899 if (tmp == NULL) {
2900 DEBUG(1, ("talloc_realloc failed\n"));
2901 exit(1);
2903 state->pending = tmp;
2905 if (buflen >= smb_size) {
2907 * place the seqnum in the packet so that the main process
2908 * can reply with signing
2910 SIVAL(buf, smb_ss_field, seqnum);
2911 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2914 iov = &state->pending[num_pending];
2915 iov->iov_base = buf;
2916 iov->iov_len = buflen;
2918 DEBUG(10,("echo_handler[%d]: forward to main\n",
2919 (int)sys_getpid()));
2920 smbd_echo_activate_writer(state);
2923 req = smbd_echo_read_send(state, state->ev, state->sconn);
2924 if (req == NULL) {
2925 DEBUG(1, ("smbd_echo_read_send failed\n"));
2926 exit(1);
2928 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2933 * Handle SMBecho requests in a forked child process
2935 bool fork_echo_handler(struct smbd_server_connection *sconn)
2937 int listener_pipe[2];
2938 int res;
2939 pid_t child;
2941 res = pipe(listener_pipe);
2942 if (res == -1) {
2943 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2944 return false;
2946 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2947 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2948 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2949 goto fail;
2952 child = sys_fork();
2953 if (child == 0) {
2954 NTSTATUS status;
2956 close(listener_pipe[0]);
2957 set_blocking(listener_pipe[1], false);
2959 status = reinit_after_fork(sconn->msg_ctx,
2960 sconn->ev_ctx,
2961 false);
2962 if (!NT_STATUS_IS_OK(status)) {
2963 DEBUG(1, ("reinit_after_fork failed: %s\n",
2964 nt_errstr(status)));
2965 exit(1);
2967 smbd_echo_loop(sconn, listener_pipe[1]);
2968 exit(0);
2970 close(listener_pipe[1]);
2971 listener_pipe[1] = -1;
2972 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2974 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2977 * Without smb signing this is the same as the normal smbd
2978 * listener. This needs to change once signing comes in.
2980 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2981 sconn,
2982 sconn->smb1.echo_handler.trusted_fd,
2983 TEVENT_FD_READ,
2984 smbd_server_echo_handler,
2985 sconn);
2986 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2987 DEBUG(1, ("event_add_fd failed\n"));
2988 goto fail;
2991 return true;
2993 fail:
2994 if (listener_pipe[0] != -1) {
2995 close(listener_pipe[0]);
2997 if (listener_pipe[1] != -1) {
2998 close(listener_pipe[1]);
3000 sconn->smb1.echo_handler.trusted_fd = -1;
3001 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3002 close(sconn->smb1.echo_handler.socket_lock_fd);
3004 sconn->smb1.echo_handler.trusted_fd = -1;
3005 sconn->smb1.echo_handler.socket_lock_fd = -1;
3006 return false;
3009 #if CLUSTER_SUPPORT
3011 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
3012 struct sockaddr_storage *srv,
3013 struct sockaddr_storage *clnt)
3015 struct ctdbd_connection *cconn;
3016 char tmp_addr[INET6_ADDRSTRLEN];
3017 char *addr;
3019 cconn = messaging_ctdbd_connection();
3020 if (cconn == NULL) {
3021 return NT_STATUS_NO_MEMORY;
3024 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
3025 addr = talloc_strdup(cconn, tmp_addr);
3026 if (addr == NULL) {
3027 return NT_STATUS_NO_MEMORY;
3029 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
3032 #endif
3034 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3036 while (user) {
3037 if (user->session_info &&
3038 (user->session_info->unix_token->uid == uid)) {
3039 return true;
3041 user = user->next;
3043 return false;
3046 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3048 while (user) {
3049 if (user->session_info != NULL) {
3050 int i;
3051 struct security_unix_token *utok;
3053 utok = user->session_info->unix_token;
3054 if (utok->gid == gid) {
3055 return true;
3057 for(i=0; i<utok->ngroups; i++) {
3058 if (utok->groups[i] == gid) {
3059 return true;
3063 user = user->next;
3065 return false;
3068 static bool sid_in_use(const struct user_struct *user,
3069 const struct dom_sid *psid)
3071 while (user) {
3072 struct security_token *tok;
3074 if (user->session_info == NULL) {
3075 continue;
3077 tok = user->session_info->security_token;
3078 if (tok == NULL) {
3080 * Not sure session_info->security_token can
3081 * ever be NULL. This check might be not
3082 * necessary.
3084 continue;
3086 if (security_token_has_sid(tok, psid)) {
3087 return true;
3089 user = user->next;
3091 return false;
3094 static bool id_in_use(const struct user_struct *user,
3095 const struct id_cache_ref *id)
3097 switch(id->type) {
3098 case UID:
3099 return uid_in_use(user, id->id.uid);
3100 case GID:
3101 return gid_in_use(user, id->id.gid);
3102 case SID:
3103 return sid_in_use(user, &id->id.sid);
3104 default:
3105 break;
3107 return false;
3110 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3111 void *private_data,
3112 uint32_t msg_type,
3113 struct server_id server_id,
3114 DATA_BLOB* data)
3116 const char *msg = (data && data->data)
3117 ? (const char *)data->data : "<NULL>";
3118 struct id_cache_ref id;
3119 struct smbd_server_connection *sconn =
3120 talloc_get_type_abort(private_data,
3121 struct smbd_server_connection);
3123 if (!id_cache_ref_parse(msg, &id)) {
3124 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3125 return;
3128 if (id_in_use(sconn->users, &id)) {
3129 exit_server_cleanly(msg);
3131 id_cache_delete_from_cache(&id);
3134 /****************************************************************************
3135 Process commands from the client
3136 ****************************************************************************/
3138 void smbd_process(struct tevent_context *ev_ctx,
3139 struct smbd_server_connection *sconn)
3141 TALLOC_CTX *frame = talloc_stackframe();
3142 struct sockaddr_storage ss;
3143 struct sockaddr *sa = NULL;
3144 socklen_t sa_socklen;
3145 struct tsocket_address *local_address = NULL;
3146 struct tsocket_address *remote_address = NULL;
3147 const char *locaddr = NULL;
3148 const char *remaddr = NULL;
3149 char *rhost;
3150 int ret;
3152 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3154 * We're not making the decision here,
3155 * we're just allowing the client
3156 * to decide between SMB1 and SMB2
3157 * with the first negprot
3158 * packet.
3160 sconn->using_smb2 = true;
3163 /* Ensure child is set to blocking mode */
3164 set_blocking(sconn->sock,True);
3166 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3167 set_socket_options(sconn->sock, lp_socket_options());
3169 sa = (struct sockaddr *)(void *)&ss;
3170 sa_socklen = sizeof(ss);
3171 ret = getpeername(sconn->sock, sa, &sa_socklen);
3172 if (ret != 0) {
3173 int level = (errno == ENOTCONN)?2:0;
3174 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3175 exit_server_cleanly("getpeername() failed.\n");
3177 ret = tsocket_address_bsd_from_sockaddr(sconn,
3178 sa, sa_socklen,
3179 &remote_address);
3180 if (ret != 0) {
3181 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3182 __location__, strerror(errno)));
3183 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3186 sa = (struct sockaddr *)(void *)&ss;
3187 sa_socklen = sizeof(ss);
3188 ret = getsockname(sconn->sock, sa, &sa_socklen);
3189 if (ret != 0) {
3190 int level = (errno == ENOTCONN)?2:0;
3191 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3192 exit_server_cleanly("getsockname() failed.\n");
3194 ret = tsocket_address_bsd_from_sockaddr(sconn,
3195 sa, sa_socklen,
3196 &local_address);
3197 if (ret != 0) {
3198 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3199 __location__, strerror(errno)));
3200 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3203 sconn->local_address = local_address;
3204 sconn->remote_address = remote_address;
3206 if (tsocket_address_is_inet(local_address, "ip")) {
3207 locaddr = tsocket_address_inet_addr_string(
3208 sconn->local_address,
3209 talloc_tos());
3210 if (locaddr == NULL) {
3211 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3212 __location__, strerror(errno)));
3213 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3215 } else {
3216 locaddr = "0.0.0.0";
3219 if (tsocket_address_is_inet(remote_address, "ip")) {
3220 remaddr = tsocket_address_inet_addr_string(
3221 sconn->remote_address,
3222 talloc_tos());
3223 if (remaddr == NULL) {
3224 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3225 __location__, strerror(errno)));
3226 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3228 } else {
3229 remaddr = "0.0.0.0";
3232 /* this is needed so that we get decent entries
3233 in smbstatus for port 445 connects */
3234 set_remote_machine_name(remaddr, false);
3235 reload_services(sconn, conn_snum_used, true);
3238 * Before the first packet, check the global hosts allow/ hosts deny
3239 * parameters before doing any parsing of packets passed to us by the
3240 * client. This prevents attacks on our parsing code from hosts not in
3241 * the hosts allow list.
3244 ret = get_remote_hostname(remote_address,
3245 &rhost,
3246 talloc_tos());
3247 if (ret < 0) {
3248 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3249 __location__, strerror(errno)));
3250 exit_server_cleanly("get_remote_hostname failed.\n");
3252 if (strequal(rhost, "UNKNOWN")) {
3253 rhost = talloc_strdup(talloc_tos(), remaddr);
3255 sconn->remote_hostname = talloc_move(sconn, &rhost);
3257 sub_set_socket_ids(remaddr,
3258 sconn->remote_hostname,
3259 locaddr);
3261 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3262 sconn->remote_hostname,
3263 remaddr)) {
3265 * send a negative session response "not listening on calling
3266 * name"
3268 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3269 DEBUG( 1, ("Connection denied from %s to %s\n",
3270 tsocket_address_string(remote_address, talloc_tos()),
3271 tsocket_address_string(local_address, talloc_tos())));
3272 (void)srv_send_smb(sconn,(char *)buf, false,
3273 0, false, NULL);
3274 exit_server_cleanly("connection denied");
3277 DEBUG(10, ("Connection allowed from %s to %s\n",
3278 tsocket_address_string(remote_address, talloc_tos()),
3279 tsocket_address_string(local_address, talloc_tos())));
3281 init_modules();
3283 smb_perfcount_init();
3285 if (!init_account_policy()) {
3286 exit_server("Could not open account policy tdb.\n");
3289 if (*lp_rootdir()) {
3290 if (chroot(lp_rootdir()) != 0) {
3291 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3292 exit_server("Failed to chroot()");
3294 if (chdir("/") == -1) {
3295 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3296 exit_server("Failed to chroot()");
3298 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3301 if (!srv_init_signing(sconn)) {
3302 exit_server("Failed to init smb_signing");
3305 /* Setup oplocks */
3306 if (!init_oplocks(sconn))
3307 exit_server("Failed to init oplocks");
3309 /* register our message handlers */
3310 messaging_register(sconn->msg_ctx, sconn,
3311 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3312 messaging_register(sconn->msg_ctx, sconn,
3313 MSG_SMB_CLOSE_FILE, msg_close_file);
3314 messaging_register(sconn->msg_ctx, sconn,
3315 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3317 id_cache_register_msgs(sconn->msg_ctx);
3318 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3319 messaging_register(sconn->msg_ctx, sconn,
3320 ID_CACHE_KILL, smbd_id_cache_kill);
3322 messaging_deregister(sconn->msg_ctx,
3323 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3324 messaging_register(sconn->msg_ctx, sconn,
3325 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3328 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3329 * MSGs to all child processes
3331 messaging_deregister(sconn->msg_ctx,
3332 MSG_DEBUG, NULL);
3333 messaging_register(sconn->msg_ctx, NULL,
3334 MSG_DEBUG, debug_message);
3336 if ((lp_keepalive() != 0)
3337 && !(event_add_idle(ev_ctx, NULL,
3338 timeval_set(lp_keepalive(), 0),
3339 "keepalive", keepalive_fn,
3340 sconn))) {
3341 DEBUG(0, ("Could not add keepalive event\n"));
3342 exit(1);
3345 if (!(event_add_idle(ev_ctx, NULL,
3346 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3347 "deadtime", deadtime_fn, sconn))) {
3348 DEBUG(0, ("Could not add deadtime event\n"));
3349 exit(1);
3352 if (!(event_add_idle(ev_ctx, NULL,
3353 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3354 "housekeeping", housekeeping_fn, sconn))) {
3355 DEBUG(0, ("Could not add housekeeping event\n"));
3356 exit(1);
3359 #ifdef CLUSTER_SUPPORT
3361 if (lp_clustering()) {
3363 * We need to tell ctdb about our client's TCP
3364 * connection, so that for failover ctdbd can send
3365 * tickle acks, triggering a reconnection by the
3366 * client.
3369 struct sockaddr_storage srv, clnt;
3371 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3372 NTSTATUS status;
3373 status = smbd_register_ips(sconn, &srv, &clnt);
3374 if (!NT_STATUS_IS_OK(status)) {
3375 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3376 nt_errstr(status)));
3378 } else
3380 DEBUG(0,("Unable to get tcp info for "
3381 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3382 strerror(errno)));
3386 #endif
3388 sconn->nbt.got_session = false;
3390 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3392 sconn->smb1.sessions.done_sesssetup = false;
3393 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3394 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3395 /* this holds info on user ids that are already validated for this VC */
3396 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3398 conn_init(sconn);
3399 if (!init_dptrs(sconn)) {
3400 exit_server("init_dptrs() failed");
3403 sconn->smb1.fde = event_add_fd(ev_ctx,
3404 sconn,
3405 sconn->sock,
3406 EVENT_FD_READ,
3407 smbd_server_connection_handler,
3408 sconn);
3409 if (!sconn->smb1.fde) {
3410 exit_server("failed to create smbd_server_connection fde");
3413 TALLOC_FREE(frame);
3415 while (True) {
3416 frame = talloc_stackframe_pool(8192);
3418 errno = 0;
3419 if (tevent_loop_once(ev_ctx) == -1) {
3420 if (errno != EINTR) {
3421 DEBUG(3, ("tevent_loop_once failed: %s,"
3422 " exiting\n", strerror(errno) ));
3423 break;
3427 TALLOC_FREE(frame);
3430 exit_server_cleanly(NULL);
3433 bool req_is_in_chain(struct smb_request *req)
3435 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3437 * We're right now handling a subsequent request, so we must
3438 * be in a chain
3440 return true;
3443 if (!is_andx_req(req->cmd)) {
3444 return false;
3447 if (req->wct < 2) {
3449 * Okay, an illegal request, but definitely not chained :-)
3451 return false;
3454 return (CVAL(req->vwv+0, 0) != 0xFF);