Start to add truncate checks on all uses of strlcpy(). Reading lwn
[Samba/gbeck.git] / source3 / smbd / process.c
blob30dbc0c6dd32d631370a49405835205508c94a12
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)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)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)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)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->smb2req = NULL;
542 req->priv_paths = NULL;
543 req->chain = NULL;
544 smb_init_perfcount_data(&req->pcd);
546 /* Ensure we have at least wct words and 2 bytes of bcc. */
547 if (smb_size + req->wct*2 > req_size) {
548 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
549 (unsigned int)req->wct,
550 (unsigned int)req_size));
551 return false;
553 /* Ensure bcc is correct. */
554 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
555 DEBUG(0,("init_smb_request: invalid bcc number %u "
556 "(wct = %u, size %u)\n",
557 (unsigned int)req->buflen,
558 (unsigned int)req->wct,
559 (unsigned int)req_size));
560 return false;
563 req->outbuf = NULL;
564 return true;
567 static void process_smb(struct smbd_server_connection *conn,
568 uint8_t *inbuf, size_t nread, size_t unread_bytes,
569 uint32_t seqnum, bool encrypted,
570 struct smb_perfcount_data *deferred_pcd);
572 static void smbd_deferred_open_timer(struct event_context *ev,
573 struct timed_event *te,
574 struct timeval _tval,
575 void *private_data)
577 struct pending_message_list *msg = talloc_get_type(private_data,
578 struct pending_message_list);
579 struct smbd_server_connection *sconn = msg->sconn;
580 TALLOC_CTX *mem_ctx = talloc_tos();
581 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
582 uint8_t *inbuf;
584 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
585 msg->buf.length);
586 if (inbuf == NULL) {
587 exit_server("smbd_deferred_open_timer: talloc failed\n");
588 return;
591 /* We leave this message on the queue so the open code can
592 know this is a retry. */
593 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
594 (unsigned long long)mid ));
596 /* Mark the message as processed so this is not
597 * re-processed in error. */
598 msg->processed = true;
600 process_smb(sconn, inbuf,
601 msg->buf.length, 0,
602 msg->seqnum, msg->encrypted, &msg->pcd);
604 /* If it's still there and was processed, remove it. */
605 msg = get_deferred_open_message_smb(sconn, mid);
606 if (msg && msg->processed) {
607 remove_deferred_open_message_smb(sconn, mid);
611 /****************************************************************************
612 Function to push a message onto the tail of a linked list of smb messages ready
613 for processing.
614 ****************************************************************************/
616 static bool push_queued_message(struct smb_request *req,
617 struct timeval request_time,
618 struct timeval end_time,
619 char *private_data, size_t private_len)
621 int msg_len = smb_len(req->inbuf) + 4;
622 struct pending_message_list *msg;
624 msg = talloc_zero(NULL, struct pending_message_list);
626 if(msg == NULL) {
627 DEBUG(0,("push_message: malloc fail (1)\n"));
628 return False;
630 msg->sconn = req->sconn;
632 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
633 if(msg->buf.data == NULL) {
634 DEBUG(0,("push_message: malloc fail (2)\n"));
635 TALLOC_FREE(msg);
636 return False;
639 msg->request_time = request_time;
640 msg->seqnum = req->seqnum;
641 msg->encrypted = req->encrypted;
642 msg->processed = false;
643 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
645 if (private_data) {
646 msg->private_data = data_blob_talloc(msg, private_data,
647 private_len);
648 if (msg->private_data.data == NULL) {
649 DEBUG(0,("push_message: malloc fail (3)\n"));
650 TALLOC_FREE(msg);
651 return False;
655 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
656 msg,
657 end_time,
658 smbd_deferred_open_timer,
659 msg);
660 if (!msg->te) {
661 DEBUG(0,("push_message: event_add_timed failed\n"));
662 TALLOC_FREE(msg);
663 return false;
666 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
667 struct pending_message_list *);
669 DEBUG(10,("push_message: pushed message length %u on "
670 "deferred_open_queue\n", (unsigned int)msg_len));
672 return True;
675 /****************************************************************************
676 Function to delete a sharing violation open message by mid.
677 ****************************************************************************/
679 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
680 uint64_t mid)
682 struct pending_message_list *pml;
684 if (sconn->using_smb2) {
685 remove_deferred_open_message_smb2(sconn, mid);
686 return;
689 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
690 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
691 DEBUG(10,("remove_deferred_open_message_smb: "
692 "deleting mid %llu len %u\n",
693 (unsigned long long)mid,
694 (unsigned int)pml->buf.length ));
695 DLIST_REMOVE(sconn->deferred_open_queue, pml);
696 TALLOC_FREE(pml);
697 return;
702 /****************************************************************************
703 Move a sharing violation open retry message to the front of the list and
704 schedule it for immediate processing.
705 ****************************************************************************/
707 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
708 uint64_t mid)
710 struct pending_message_list *pml;
711 int i = 0;
713 if (sconn->using_smb2) {
714 schedule_deferred_open_message_smb2(sconn, mid);
715 return;
718 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
719 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
721 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
722 "msg_mid = %llu\n",
723 i++,
724 (unsigned long long)msg_mid ));
726 if (mid == msg_mid) {
727 struct timed_event *te;
729 if (pml->processed) {
730 /* A processed message should not be
731 * rescheduled. */
732 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
733 "message mid %llu was already processed\n",
734 (unsigned long long)msg_mid ));
735 continue;
738 DEBUG(10,("schedule_deferred_open_message_smb: "
739 "scheduling mid %llu\n",
740 (unsigned long long)mid ));
742 te = tevent_add_timer(pml->sconn->ev_ctx,
743 pml,
744 timeval_zero(),
745 smbd_deferred_open_timer,
746 pml);
747 if (!te) {
748 DEBUG(10,("schedule_deferred_open_message_smb: "
749 "event_add_timed() failed, "
750 "skipping mid %llu\n",
751 (unsigned long long)msg_mid ));
754 TALLOC_FREE(pml->te);
755 pml->te = te;
756 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
757 return;
761 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
762 "find message mid %llu\n",
763 (unsigned long long)mid ));
766 /****************************************************************************
767 Return true if this mid is on the deferred queue and was not yet processed.
768 ****************************************************************************/
770 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
772 struct pending_message_list *pml;
774 if (sconn->using_smb2) {
775 return open_was_deferred_smb2(sconn, mid);
778 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
779 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
780 return True;
783 return False;
786 /****************************************************************************
787 Return the message queued by this mid.
788 ****************************************************************************/
790 static struct pending_message_list *get_deferred_open_message_smb(
791 struct smbd_server_connection *sconn, uint64_t mid)
793 struct pending_message_list *pml;
795 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
796 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
797 return pml;
800 return NULL;
803 /****************************************************************************
804 Get the state data queued by this mid.
805 ****************************************************************************/
807 bool get_deferred_open_message_state(struct smb_request *smbreq,
808 struct timeval *p_request_time,
809 void **pp_state)
811 struct pending_message_list *pml;
813 if (smbreq->sconn->using_smb2) {
814 return get_deferred_open_message_state_smb2(smbreq->smb2req,
815 p_request_time,
816 pp_state);
819 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
820 if (!pml) {
821 return false;
823 if (p_request_time) {
824 *p_request_time = pml->request_time;
826 if (pp_state) {
827 *pp_state = (void *)pml->private_data.data;
829 return true;
832 /****************************************************************************
833 Function to push a deferred open smb message onto a linked list of local smb
834 messages ready for processing.
835 ****************************************************************************/
837 bool push_deferred_open_message_smb(struct smb_request *req,
838 struct timeval request_time,
839 struct timeval timeout,
840 struct file_id id,
841 char *private_data, size_t priv_len)
843 struct timeval end_time;
845 if (req->smb2req) {
846 return push_deferred_open_message_smb2(req->smb2req,
847 request_time,
848 timeout,
850 private_data,
851 priv_len);
854 if (req->unread_bytes) {
855 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
856 "unread_bytes = %u\n",
857 (unsigned int)req->unread_bytes ));
858 smb_panic("push_deferred_open_message_smb: "
859 "logic error unread_bytes != 0" );
862 end_time = timeval_sum(&request_time, &timeout);
864 DEBUG(10,("push_deferred_open_message_smb: pushing message "
865 "len %u mid %llu timeout time [%u.%06u]\n",
866 (unsigned int) smb_len(req->inbuf)+4,
867 (unsigned long long)req->mid,
868 (unsigned int)end_time.tv_sec,
869 (unsigned int)end_time.tv_usec));
871 return push_queued_message(req, request_time, end_time,
872 private_data, priv_len);
875 static void smbd_sig_term_handler(struct tevent_context *ev,
876 struct tevent_signal *se,
877 int signum,
878 int count,
879 void *siginfo,
880 void *private_data)
882 exit_server_cleanly("termination signal");
885 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
887 struct tevent_signal *se;
889 se = tevent_add_signal(sconn->ev_ctx,
890 sconn,
891 SIGTERM, 0,
892 smbd_sig_term_handler,
893 sconn);
894 if (!se) {
895 exit_server("failed to setup SIGTERM handler");
899 static void smbd_sig_hup_handler(struct tevent_context *ev,
900 struct tevent_signal *se,
901 int signum,
902 int count,
903 void *siginfo,
904 void *private_data)
906 struct smbd_server_connection *sconn =
907 talloc_get_type_abort(private_data,
908 struct smbd_server_connection);
910 change_to_root_user();
911 DEBUG(1,("Reloading services after SIGHUP\n"));
912 reload_services(sconn, conn_snum_used, false);
915 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
917 struct tevent_signal *se;
919 se = tevent_add_signal(sconn->ev_ctx,
920 sconn,
921 SIGHUP, 0,
922 smbd_sig_hup_handler,
923 sconn);
924 if (!se) {
925 exit_server("failed to setup SIGHUP handler");
929 static void smbd_conf_updated(struct messaging_context *msg,
930 void *private_data,
931 uint32_t msg_type,
932 struct server_id server_id,
933 DATA_BLOB *data)
935 struct smbd_server_connection *sconn =
936 talloc_get_type_abort(private_data,
937 struct smbd_server_connection);
939 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
940 "updated. Reloading.\n"));
941 change_to_root_user();
942 reload_services(sconn, conn_snum_used, false);
946 * Only allow 5 outstanding trans requests. We're allocating memory, so
947 * prevent a DoS.
950 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
952 int count = 0;
953 for (; list != NULL; list = list->next) {
955 if (list->mid == mid) {
956 return NT_STATUS_INVALID_PARAMETER;
959 count += 1;
961 if (count > 5) {
962 return NT_STATUS_INSUFFICIENT_RESOURCES;
965 return NT_STATUS_OK;
969 These flags determine some of the permissions required to do an operation
971 Note that I don't set NEED_WRITE on some write operations because they
972 are used by some brain-dead clients when printing, and I don't want to
973 force write permissions on print services.
975 #define AS_USER (1<<0)
976 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
977 #define TIME_INIT (1<<2)
978 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
979 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
980 #define DO_CHDIR (1<<6)
983 define a list of possible SMB messages and their corresponding
984 functions. Any message that has a NULL function is unimplemented -
985 please feel free to contribute implementations!
987 static const struct smb_message_struct {
988 const char *name;
989 void (*fn)(struct smb_request *req);
990 int flags;
991 } smb_messages[256] = {
993 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
994 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
995 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
996 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
997 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
998 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
999 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1000 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1001 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1002 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1003 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1004 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1005 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1006 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1007 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1008 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1009 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1010 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1011 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1012 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1013 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1014 /* 0x15 */ { NULL, NULL, 0 },
1015 /* 0x16 */ { NULL, NULL, 0 },
1016 /* 0x17 */ { NULL, NULL, 0 },
1017 /* 0x18 */ { NULL, NULL, 0 },
1018 /* 0x19 */ { NULL, NULL, 0 },
1019 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1020 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1021 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1022 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1023 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1024 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1025 /* 0x20 */ { "SMBwritec", NULL,0},
1026 /* 0x21 */ { NULL, NULL, 0 },
1027 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1028 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1029 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1030 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1031 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1032 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1033 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1034 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1035 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1036 /* 0x2b */ { "SMBecho",reply_echo,0},
1037 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1038 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1039 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1040 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1041 /* 0x30 */ { NULL, NULL, 0 },
1042 /* 0x31 */ { NULL, NULL, 0 },
1043 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1044 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1045 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1046 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1047 /* 0x36 */ { NULL, NULL, 0 },
1048 /* 0x37 */ { NULL, NULL, 0 },
1049 /* 0x38 */ { NULL, NULL, 0 },
1050 /* 0x39 */ { NULL, NULL, 0 },
1051 /* 0x3a */ { NULL, NULL, 0 },
1052 /* 0x3b */ { NULL, NULL, 0 },
1053 /* 0x3c */ { NULL, NULL, 0 },
1054 /* 0x3d */ { NULL, NULL, 0 },
1055 /* 0x3e */ { NULL, NULL, 0 },
1056 /* 0x3f */ { NULL, NULL, 0 },
1057 /* 0x40 */ { NULL, NULL, 0 },
1058 /* 0x41 */ { NULL, NULL, 0 },
1059 /* 0x42 */ { NULL, NULL, 0 },
1060 /* 0x43 */ { NULL, NULL, 0 },
1061 /* 0x44 */ { NULL, NULL, 0 },
1062 /* 0x45 */ { NULL, NULL, 0 },
1063 /* 0x46 */ { NULL, NULL, 0 },
1064 /* 0x47 */ { NULL, NULL, 0 },
1065 /* 0x48 */ { NULL, NULL, 0 },
1066 /* 0x49 */ { NULL, NULL, 0 },
1067 /* 0x4a */ { NULL, NULL, 0 },
1068 /* 0x4b */ { NULL, NULL, 0 },
1069 /* 0x4c */ { NULL, NULL, 0 },
1070 /* 0x4d */ { NULL, NULL, 0 },
1071 /* 0x4e */ { NULL, NULL, 0 },
1072 /* 0x4f */ { NULL, NULL, 0 },
1073 /* 0x50 */ { NULL, NULL, 0 },
1074 /* 0x51 */ { NULL, NULL, 0 },
1075 /* 0x52 */ { NULL, NULL, 0 },
1076 /* 0x53 */ { NULL, NULL, 0 },
1077 /* 0x54 */ { NULL, NULL, 0 },
1078 /* 0x55 */ { NULL, NULL, 0 },
1079 /* 0x56 */ { NULL, NULL, 0 },
1080 /* 0x57 */ { NULL, NULL, 0 },
1081 /* 0x58 */ { NULL, NULL, 0 },
1082 /* 0x59 */ { NULL, NULL, 0 },
1083 /* 0x5a */ { NULL, NULL, 0 },
1084 /* 0x5b */ { NULL, NULL, 0 },
1085 /* 0x5c */ { NULL, NULL, 0 },
1086 /* 0x5d */ { NULL, NULL, 0 },
1087 /* 0x5e */ { NULL, NULL, 0 },
1088 /* 0x5f */ { NULL, NULL, 0 },
1089 /* 0x60 */ { NULL, NULL, 0 },
1090 /* 0x61 */ { NULL, NULL, 0 },
1091 /* 0x62 */ { NULL, NULL, 0 },
1092 /* 0x63 */ { NULL, NULL, 0 },
1093 /* 0x64 */ { NULL, NULL, 0 },
1094 /* 0x65 */ { NULL, NULL, 0 },
1095 /* 0x66 */ { NULL, NULL, 0 },
1096 /* 0x67 */ { NULL, NULL, 0 },
1097 /* 0x68 */ { NULL, NULL, 0 },
1098 /* 0x69 */ { NULL, NULL, 0 },
1099 /* 0x6a */ { NULL, NULL, 0 },
1100 /* 0x6b */ { NULL, NULL, 0 },
1101 /* 0x6c */ { NULL, NULL, 0 },
1102 /* 0x6d */ { NULL, NULL, 0 },
1103 /* 0x6e */ { NULL, NULL, 0 },
1104 /* 0x6f */ { NULL, NULL, 0 },
1105 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1106 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1107 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1108 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1109 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1110 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1111 /* 0x76 */ { NULL, NULL, 0 },
1112 /* 0x77 */ { NULL, NULL, 0 },
1113 /* 0x78 */ { NULL, NULL, 0 },
1114 /* 0x79 */ { NULL, NULL, 0 },
1115 /* 0x7a */ { NULL, NULL, 0 },
1116 /* 0x7b */ { NULL, NULL, 0 },
1117 /* 0x7c */ { NULL, NULL, 0 },
1118 /* 0x7d */ { NULL, NULL, 0 },
1119 /* 0x7e */ { NULL, NULL, 0 },
1120 /* 0x7f */ { NULL, NULL, 0 },
1121 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1122 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1123 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1124 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1125 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1126 /* 0x85 */ { NULL, NULL, 0 },
1127 /* 0x86 */ { NULL, NULL, 0 },
1128 /* 0x87 */ { NULL, NULL, 0 },
1129 /* 0x88 */ { NULL, NULL, 0 },
1130 /* 0x89 */ { NULL, NULL, 0 },
1131 /* 0x8a */ { NULL, NULL, 0 },
1132 /* 0x8b */ { NULL, NULL, 0 },
1133 /* 0x8c */ { NULL, NULL, 0 },
1134 /* 0x8d */ { NULL, NULL, 0 },
1135 /* 0x8e */ { NULL, NULL, 0 },
1136 /* 0x8f */ { NULL, NULL, 0 },
1137 /* 0x90 */ { NULL, NULL, 0 },
1138 /* 0x91 */ { NULL, NULL, 0 },
1139 /* 0x92 */ { NULL, NULL, 0 },
1140 /* 0x93 */ { NULL, NULL, 0 },
1141 /* 0x94 */ { NULL, NULL, 0 },
1142 /* 0x95 */ { NULL, NULL, 0 },
1143 /* 0x96 */ { NULL, NULL, 0 },
1144 /* 0x97 */ { NULL, NULL, 0 },
1145 /* 0x98 */ { NULL, NULL, 0 },
1146 /* 0x99 */ { NULL, NULL, 0 },
1147 /* 0x9a */ { NULL, NULL, 0 },
1148 /* 0x9b */ { NULL, NULL, 0 },
1149 /* 0x9c */ { NULL, NULL, 0 },
1150 /* 0x9d */ { NULL, NULL, 0 },
1151 /* 0x9e */ { NULL, NULL, 0 },
1152 /* 0x9f */ { NULL, NULL, 0 },
1153 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1154 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1155 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1156 /* 0xa3 */ { NULL, NULL, 0 },
1157 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1158 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1159 /* 0xa6 */ { NULL, NULL, 0 },
1160 /* 0xa7 */ { NULL, NULL, 0 },
1161 /* 0xa8 */ { NULL, NULL, 0 },
1162 /* 0xa9 */ { NULL, NULL, 0 },
1163 /* 0xaa */ { NULL, NULL, 0 },
1164 /* 0xab */ { NULL, NULL, 0 },
1165 /* 0xac */ { NULL, NULL, 0 },
1166 /* 0xad */ { NULL, NULL, 0 },
1167 /* 0xae */ { NULL, NULL, 0 },
1168 /* 0xaf */ { NULL, NULL, 0 },
1169 /* 0xb0 */ { NULL, NULL, 0 },
1170 /* 0xb1 */ { NULL, NULL, 0 },
1171 /* 0xb2 */ { NULL, NULL, 0 },
1172 /* 0xb3 */ { NULL, NULL, 0 },
1173 /* 0xb4 */ { NULL, NULL, 0 },
1174 /* 0xb5 */ { NULL, NULL, 0 },
1175 /* 0xb6 */ { NULL, NULL, 0 },
1176 /* 0xb7 */ { NULL, NULL, 0 },
1177 /* 0xb8 */ { NULL, NULL, 0 },
1178 /* 0xb9 */ { NULL, NULL, 0 },
1179 /* 0xba */ { NULL, NULL, 0 },
1180 /* 0xbb */ { NULL, NULL, 0 },
1181 /* 0xbc */ { NULL, NULL, 0 },
1182 /* 0xbd */ { NULL, NULL, 0 },
1183 /* 0xbe */ { NULL, NULL, 0 },
1184 /* 0xbf */ { NULL, NULL, 0 },
1185 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1186 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1187 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1188 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1189 /* 0xc4 */ { NULL, NULL, 0 },
1190 /* 0xc5 */ { NULL, NULL, 0 },
1191 /* 0xc6 */ { NULL, NULL, 0 },
1192 /* 0xc7 */ { NULL, NULL, 0 },
1193 /* 0xc8 */ { NULL, NULL, 0 },
1194 /* 0xc9 */ { NULL, NULL, 0 },
1195 /* 0xca */ { NULL, NULL, 0 },
1196 /* 0xcb */ { NULL, NULL, 0 },
1197 /* 0xcc */ { NULL, NULL, 0 },
1198 /* 0xcd */ { NULL, NULL, 0 },
1199 /* 0xce */ { NULL, NULL, 0 },
1200 /* 0xcf */ { NULL, NULL, 0 },
1201 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1202 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1203 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1204 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1205 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1206 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1207 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1208 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1209 /* 0xd8 */ { NULL, NULL, 0 },
1210 /* 0xd9 */ { NULL, NULL, 0 },
1211 /* 0xda */ { NULL, NULL, 0 },
1212 /* 0xdb */ { NULL, NULL, 0 },
1213 /* 0xdc */ { NULL, NULL, 0 },
1214 /* 0xdd */ { NULL, NULL, 0 },
1215 /* 0xde */ { NULL, NULL, 0 },
1216 /* 0xdf */ { NULL, NULL, 0 },
1217 /* 0xe0 */ { NULL, NULL, 0 },
1218 /* 0xe1 */ { NULL, NULL, 0 },
1219 /* 0xe2 */ { NULL, NULL, 0 },
1220 /* 0xe3 */ { NULL, NULL, 0 },
1221 /* 0xe4 */ { NULL, NULL, 0 },
1222 /* 0xe5 */ { NULL, NULL, 0 },
1223 /* 0xe6 */ { NULL, NULL, 0 },
1224 /* 0xe7 */ { NULL, NULL, 0 },
1225 /* 0xe8 */ { NULL, NULL, 0 },
1226 /* 0xe9 */ { NULL, NULL, 0 },
1227 /* 0xea */ { NULL, NULL, 0 },
1228 /* 0xeb */ { NULL, NULL, 0 },
1229 /* 0xec */ { NULL, NULL, 0 },
1230 /* 0xed */ { NULL, NULL, 0 },
1231 /* 0xee */ { NULL, NULL, 0 },
1232 /* 0xef */ { NULL, NULL, 0 },
1233 /* 0xf0 */ { NULL, NULL, 0 },
1234 /* 0xf1 */ { NULL, NULL, 0 },
1235 /* 0xf2 */ { NULL, NULL, 0 },
1236 /* 0xf3 */ { NULL, NULL, 0 },
1237 /* 0xf4 */ { NULL, NULL, 0 },
1238 /* 0xf5 */ { NULL, NULL, 0 },
1239 /* 0xf6 */ { NULL, NULL, 0 },
1240 /* 0xf7 */ { NULL, NULL, 0 },
1241 /* 0xf8 */ { NULL, NULL, 0 },
1242 /* 0xf9 */ { NULL, NULL, 0 },
1243 /* 0xfa */ { NULL, NULL, 0 },
1244 /* 0xfb */ { NULL, NULL, 0 },
1245 /* 0xfc */ { NULL, NULL, 0 },
1246 /* 0xfd */ { NULL, NULL, 0 },
1247 /* 0xfe */ { NULL, NULL, 0 },
1248 /* 0xff */ { NULL, NULL, 0 }
1252 /*******************************************************************
1253 allocate and initialize a reply packet
1254 ********************************************************************/
1256 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1257 const char *inbuf, char **outbuf, uint8_t num_words,
1258 uint32_t num_bytes)
1261 * Protect against integer wrap
1263 if ((num_bytes > 0xffffff)
1264 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1265 char *msg;
1266 if (asprintf(&msg, "num_bytes too large: %u",
1267 (unsigned)num_bytes) == -1) {
1268 msg = discard_const_p(char, "num_bytes too large");
1270 smb_panic(msg);
1273 *outbuf = talloc_array(mem_ctx, char,
1274 smb_size + num_words*2 + num_bytes);
1275 if (*outbuf == NULL) {
1276 return false;
1279 construct_reply_common(req, inbuf, *outbuf);
1280 srv_set_message(*outbuf, num_words, num_bytes, false);
1282 * Zero out the word area, the caller has to take care of the bcc area
1283 * himself
1285 if (num_words != 0) {
1286 memset(*outbuf + smb_vwv0, 0, num_words*2);
1289 return true;
1292 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1294 char *outbuf;
1295 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1296 num_bytes)) {
1297 smb_panic("could not allocate output buffer\n");
1299 req->outbuf = (uint8_t *)outbuf;
1303 /*******************************************************************
1304 Dump a packet to a file.
1305 ********************************************************************/
1307 static void smb_dump(const char *name, int type, const char *data)
1309 size_t len;
1310 int fd, i;
1311 char *fname = NULL;
1312 if (DEBUGLEVEL < 50) {
1313 return;
1316 len = smb_len_tcp(data)+4;
1317 for (i=1;i<100;i++) {
1318 fname = talloc_asprintf(talloc_tos(),
1319 "/tmp/%s.%d.%s",
1320 name,
1322 type ? "req" : "resp");
1323 if (fname == NULL) {
1324 return;
1326 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1327 if (fd != -1 || errno != EEXIST) break;
1328 TALLOC_FREE(fname);
1330 if (fd != -1) {
1331 ssize_t ret = write(fd, data, len);
1332 if (ret != len)
1333 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1334 close(fd);
1335 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1337 TALLOC_FREE(fname);
1340 /****************************************************************************
1341 Prepare everything for calling the actual request function, and potentially
1342 call the request function via the "new" interface.
1344 Return False if the "legacy" function needs to be called, everything is
1345 prepared.
1347 Return True if we're done.
1349 I know this API sucks, but it is the one with the least code change I could
1350 find.
1351 ****************************************************************************/
1353 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1355 int flags;
1356 uint16 session_tag;
1357 connection_struct *conn = NULL;
1358 struct smbd_server_connection *sconn = req->sconn;
1360 errno = 0;
1362 if (smb_messages[type].fn == NULL) {
1363 DEBUG(0,("Unknown message type %d!\n",type));
1364 smb_dump("Unknown", 1, (const char *)req->inbuf);
1365 reply_unknown_new(req, type);
1366 return NULL;
1369 flags = smb_messages[type].flags;
1371 /* In share mode security we must ignore the vuid. */
1372 session_tag = req->vuid;
1373 conn = req->conn;
1375 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1376 (int)getpid(), (unsigned long)conn));
1378 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1380 /* Ensure this value is replaced in the incoming packet. */
1381 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1384 * Ensure the correct username is in current_user_info. This is a
1385 * really ugly bugfix for problems with multiple session_setup_and_X's
1386 * being done and allowing %U and %G substitutions to work correctly.
1387 * There is a reason this code is done here, don't move it unless you
1388 * know what you're doing... :-).
1389 * JRA.
1392 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1393 user_struct *vuser = NULL;
1395 sconn->smb1.sessions.last_session_tag = session_tag;
1396 if(session_tag != UID_FIELD_INVALID) {
1397 vuser = get_valid_user_struct(sconn, session_tag);
1398 if (vuser) {
1399 set_current_user_info(
1400 vuser->session_info->unix_info->sanitized_username,
1401 vuser->session_info->unix_info->unix_name,
1402 vuser->session_info->info->domain_name);
1407 /* Does this call need to be run as the connected user? */
1408 if (flags & AS_USER) {
1410 /* Does this call need a valid tree connection? */
1411 if (!conn) {
1413 * Amazingly, the error code depends on the command
1414 * (from Samba4).
1416 if (type == SMBntcreateX) {
1417 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1418 } else {
1419 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1421 return NULL;
1424 if (!change_to_user(conn,session_tag)) {
1425 DEBUG(0, ("Error: Could not change to user. Removing "
1426 "deferred open, mid=%llu.\n",
1427 (unsigned long long)req->mid));
1428 reply_force_doserror(req, ERRSRV, ERRbaduid);
1429 return conn;
1432 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1434 /* Does it need write permission? */
1435 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1436 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1437 return conn;
1440 /* IPC services are limited */
1441 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1442 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1443 return conn;
1445 } else {
1446 /* This call needs to be run as root */
1447 change_to_root_user();
1450 /* load service specific parameters */
1451 if (conn) {
1452 if (req->encrypted) {
1453 conn->encrypted_tid = true;
1454 /* encrypted required from now on. */
1455 conn->encrypt_level = Required;
1456 } else if (ENCRYPTION_REQUIRED(conn)) {
1457 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1458 exit_server_cleanly("encryption required "
1459 "on connection");
1460 return conn;
1464 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1465 (flags & (AS_USER|DO_CHDIR)
1466 ?True:False))) {
1467 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1468 return conn;
1470 conn->num_smb_operations++;
1474 * Does this protocol need to be run as guest? (Only archane
1475 * messenger service requests have this...)
1477 if (flags & AS_GUEST) {
1478 char *raddr;
1479 bool ok;
1481 if (!change_to_guest()) {
1482 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1483 return conn;
1486 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1487 talloc_tos());
1488 if (raddr == NULL) {
1489 reply_nterror(req, NT_STATUS_NO_MEMORY);
1490 return conn;
1494 * Haven't we checked this in smbd_process already???
1497 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1498 sconn->remote_hostname, raddr);
1499 TALLOC_FREE(raddr);
1501 if (!ok) {
1502 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1503 return conn;
1507 smb_messages[type].fn(req);
1508 return req->conn;
1511 /****************************************************************************
1512 Construct a reply to the incoming packet.
1513 ****************************************************************************/
1515 static void construct_reply(struct smbd_server_connection *sconn,
1516 char *inbuf, int size, size_t unread_bytes,
1517 uint32_t seqnum, bool encrypted,
1518 struct smb_perfcount_data *deferred_pcd)
1520 connection_struct *conn;
1521 struct smb_request *req;
1523 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1524 smb_panic("could not allocate smb_request");
1527 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1528 encrypted, seqnum)) {
1529 exit_server_cleanly("Invalid SMB request");
1532 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1534 /* we popped this message off the queue - keep original perf data */
1535 if (deferred_pcd)
1536 req->pcd = *deferred_pcd;
1537 else {
1538 SMB_PERFCOUNT_START(&req->pcd);
1539 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1540 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1543 conn = switch_message(req->cmd, req);
1545 if (req->outbuf == NULL) {
1546 return;
1549 if (CVAL(req->outbuf,0) == 0) {
1550 show_msg((char *)req->outbuf);
1553 if (!srv_send_smb(req->sconn,
1554 (char *)req->outbuf,
1555 true, req->seqnum+1,
1556 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1557 &req->pcd)) {
1558 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1561 TALLOC_FREE(req);
1563 return;
1566 static void construct_reply_chain(struct smbd_server_connection *sconn,
1567 char *inbuf, int size, uint32_t seqnum,
1568 bool encrypted,
1569 struct smb_perfcount_data *deferred_pcd)
1571 struct smb_request **reqs = NULL;
1572 struct smb_request *req;
1573 unsigned num_reqs;
1574 bool ok;
1576 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1577 seqnum, &reqs, &num_reqs);
1578 if (!ok) {
1579 char errbuf[smb_size];
1580 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1581 __LINE__, __FILE__);
1582 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1583 NULL)) {
1584 exit_server_cleanly("construct_reply_chain: "
1585 "srv_send_smb failed.");
1587 return;
1590 req = reqs[0];
1591 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1593 req->conn = switch_message(req->cmd, req);
1595 if (req->outbuf == NULL) {
1597 * Request has suspended itself, will come
1598 * back here.
1600 return;
1602 smb_request_done(req);
1606 * To be called from an async SMB handler that is potentially chained
1607 * when it is finished for shipping.
1610 void smb_request_done(struct smb_request *req)
1612 struct smb_request **reqs = NULL;
1613 struct smb_request *first_req;
1614 size_t i, num_reqs, next_index;
1615 NTSTATUS status;
1617 if (req->chain == NULL) {
1618 first_req = req;
1619 goto shipit;
1622 reqs = req->chain;
1623 num_reqs = talloc_array_length(reqs);
1625 for (i=0; i<num_reqs; i++) {
1626 if (reqs[i] == req) {
1627 break;
1630 if (i == num_reqs) {
1632 * Invalid chain, should not happen
1634 status = NT_STATUS_INTERNAL_ERROR;
1635 goto error;
1637 next_index = i+1;
1639 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1640 struct smb_request *next = reqs[next_index];
1642 next->vuid = SVAL(req->outbuf, smb_uid);
1643 next->tid = SVAL(req->outbuf, smb_tid);
1644 next->conn = conn_find(req->sconn, req->tid);
1645 next->chain_fsp = req->chain_fsp;
1646 next->inbuf = (uint8_t *)req->inbuf;
1648 req = next;
1649 req->conn = switch_message(req->cmd, req);
1651 if (req->outbuf == NULL) {
1653 * Request has suspended itself, will come
1654 * back here.
1656 return;
1658 next_index += 1;
1661 first_req = reqs[0];
1663 for (i=1; i<next_index; i++) {
1664 bool ok;
1666 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1667 if (!ok) {
1668 status = NT_STATUS_INTERNAL_ERROR;
1669 goto error;
1673 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1674 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1677 * This scary statement intends to set the
1678 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1679 * to the value last_req->outbuf carries
1681 SSVAL(first_req->outbuf, smb_flg2,
1682 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1683 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1686 * Transfer the error codes from the subrequest to the main one
1688 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1689 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1691 _smb_setlen_large(
1692 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1694 shipit:
1695 if (!srv_send_smb(first_req->sconn,
1696 (char *)first_req->outbuf,
1697 true, first_req->seqnum+1,
1698 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1699 &first_req->pcd)) {
1700 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1701 "failed.");
1703 TALLOC_FREE(req); /* non-chained case */
1704 TALLOC_FREE(reqs); /* chained case */
1705 return;
1707 error:
1709 char errbuf[smb_size];
1710 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1711 if (!srv_send_smb(req->sconn, errbuf, true,
1712 req->seqnum+1, req->encrypted,
1713 NULL)) {
1714 exit_server_cleanly("construct_reply_chain: "
1715 "srv_send_smb failed.");
1718 TALLOC_FREE(req); /* non-chained case */
1719 TALLOC_FREE(reqs); /* chained case */
1722 /****************************************************************************
1723 Process an smb from the client
1724 ****************************************************************************/
1725 static void process_smb(struct smbd_server_connection *sconn,
1726 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1727 uint32_t seqnum, bool encrypted,
1728 struct smb_perfcount_data *deferred_pcd)
1730 int msg_type = CVAL(inbuf,0);
1732 DO_PROFILE_INC(smb_count);
1734 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1735 smb_len(inbuf) ) );
1736 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1737 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1739 if (msg_type != NBSSmessage) {
1741 * NetBIOS session request, keepalive, etc.
1743 reply_special(sconn, (char *)inbuf, nread);
1744 goto done;
1747 if (sconn->using_smb2) {
1748 /* At this point we're not really using smb2,
1749 * we make the decision here.. */
1750 if (smbd_is_smb2_header(inbuf, nread)) {
1751 smbd_smb2_first_negprot(sconn, inbuf, nread);
1752 return;
1753 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1754 && CVAL(inbuf, smb_com) != 0x72) {
1755 /* This is a non-negprot SMB1 packet.
1756 Disable SMB2 from now on. */
1757 sconn->using_smb2 = false;
1761 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1762 * so subtract 4 from it. */
1763 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1764 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1765 smb_len(inbuf)));
1767 /* special magic for immediate exit */
1768 if ((nread == 9) &&
1769 (IVAL(inbuf, 4) == 0x74697865) &&
1770 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1771 uint8_t exitcode = CVAL(inbuf, 8);
1772 DEBUG(1, ("Exiting immediately with code %d\n",
1773 (int)exitcode));
1774 exit(exitcode);
1777 exit_server_cleanly("Non-SMB packet");
1780 show_msg((char *)inbuf);
1782 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1783 construct_reply_chain(sconn, (char *)inbuf, nread,
1784 seqnum, encrypted, deferred_pcd);
1785 } else {
1786 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1787 seqnum, encrypted, deferred_pcd);
1790 sconn->trans_num++;
1792 done:
1793 sconn->num_requests++;
1795 /* The timeout_processing function isn't run nearly
1796 often enough to implement 'max log size' without
1797 overrunning the size of the file by many megabytes.
1798 This is especially true if we are running at debug
1799 level 10. Checking every 50 SMBs is a nice
1800 tradeoff of performance vs log file size overrun. */
1802 if ((sconn->num_requests % 50) == 0 &&
1803 need_to_check_log_size()) {
1804 change_to_root_user();
1805 check_log_size();
1809 /****************************************************************************
1810 Return a string containing the function name of a SMB command.
1811 ****************************************************************************/
1813 const char *smb_fn_name(int type)
1815 const char *unknown_name = "SMBunknown";
1817 if (smb_messages[type].name == NULL)
1818 return(unknown_name);
1820 return(smb_messages[type].name);
1823 /****************************************************************************
1824 Helper functions for contruct_reply.
1825 ****************************************************************************/
1827 void add_to_common_flags2(uint32 v)
1829 common_flags2 |= v;
1832 void remove_from_common_flags2(uint32 v)
1834 common_flags2 &= ~v;
1837 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1838 char *outbuf)
1840 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1841 uint16_t out_flags2 = common_flags2;
1843 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1844 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1845 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1847 srv_set_message(outbuf,0,0,false);
1849 SCVAL(outbuf, smb_com, req->cmd);
1850 SIVAL(outbuf,smb_rcls,0);
1851 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1852 SSVAL(outbuf,smb_flg2, out_flags2);
1853 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1854 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1856 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1857 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1858 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1859 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1862 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1864 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1868 * @brief Find the smb_cmd offset of the last command pushed
1869 * @param[in] buf The buffer we're building up
1870 * @retval Where can we put our next andx cmd?
1872 * While chaining requests, the "next" request we're looking at needs to put
1873 * its SMB_Command before the data the previous request already built up added
1874 * to the chain. Find the offset to the place where we have to put our cmd.
1877 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1879 uint8_t cmd;
1880 size_t ofs;
1882 cmd = CVAL(buf, smb_com);
1884 if (!is_andx_req(cmd)) {
1885 return false;
1888 ofs = smb_vwv0;
1890 while (CVAL(buf, ofs) != 0xff) {
1892 if (!is_andx_req(CVAL(buf, ofs))) {
1893 return false;
1897 * ofs is from start of smb header, so add the 4 length
1898 * bytes. The next cmd is right after the wct field.
1900 ofs = SVAL(buf, ofs+2) + 4 + 1;
1902 if (ofs+4 >= talloc_get_size(buf)) {
1903 return false;
1907 *pofs = ofs;
1908 return true;
1912 * @brief Do the smb chaining at a buffer level
1913 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1914 * @param[in] andx_buf Buffer to be appended
1917 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1919 uint8_t smb_command = CVAL(andx_buf, smb_com);
1920 uint8_t wct = CVAL(andx_buf, smb_wct);
1921 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1922 uint32_t num_bytes = smb_buflen(andx_buf);
1923 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1925 uint8_t *outbuf;
1926 size_t old_size, new_size;
1927 size_t ofs;
1928 size_t chain_padding = 0;
1929 size_t andx_cmd_ofs;
1932 old_size = talloc_get_size(*poutbuf);
1934 if ((old_size % 4) != 0) {
1936 * Align the wct field of subsequent requests to a 4-byte
1937 * boundary
1939 chain_padding = 4 - (old_size % 4);
1943 * After the old request comes the new wct field (1 byte), the vwv's
1944 * and the num_bytes field.
1947 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1948 new_size += num_bytes;
1950 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1951 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1952 (unsigned)new_size));
1953 return false;
1956 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1957 if (outbuf == NULL) {
1958 DEBUG(0, ("talloc failed\n"));
1959 return false;
1961 *poutbuf = outbuf;
1963 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1964 DEBUG(1, ("invalid command chain\n"));
1965 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
1966 return false;
1969 if (chain_padding != 0) {
1970 memset(outbuf + old_size, 0, chain_padding);
1971 old_size += chain_padding;
1974 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1975 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1977 ofs = old_size;
1980 * Push the chained request:
1982 * wct field
1985 SCVAL(outbuf, ofs, wct);
1986 ofs += 1;
1989 * vwv array
1992 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1995 * HACK ALERT
1997 * Read&X has an offset into its data buffer at
1998 * vwv[6]. reply_read_andx has no idea anymore that it's
1999 * running from within a chain, so we have to fix up the
2000 * offset here.
2002 * Although it looks disgusting at this place, I want to keep
2003 * it here. The alternative would be to push knowledge about
2004 * the andx chain down into read&x again.
2007 if (smb_command == SMBreadX) {
2008 uint8_t *bytes_addr;
2010 if (wct < 7) {
2012 * Invalid read&x response
2014 return false;
2017 bytes_addr = outbuf + ofs /* vwv start */
2018 + sizeof(uint16_t) * wct /* vwv array */
2019 + sizeof(uint16_t); /* bcc */
2021 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2022 bytes_addr - outbuf - 4);
2025 ofs += sizeof(uint16_t) * wct;
2028 * bcc (byte count)
2031 SSVAL(outbuf, ofs, num_bytes);
2032 ofs += sizeof(uint16_t);
2035 * The bytes field
2038 memcpy(outbuf + ofs, bytes, num_bytes);
2040 return true;
2043 bool smb1_is_chain(const uint8_t *buf)
2045 uint8_t cmd, wct, andx_cmd;
2047 cmd = CVAL(buf, smb_com);
2048 if (!is_andx_req(cmd)) {
2049 return false;
2051 wct = CVAL(buf, smb_wct);
2052 if (wct < 2) {
2053 return false;
2055 andx_cmd = CVAL(buf, smb_vwv);
2056 return (andx_cmd != 0xFF);
2059 bool smb1_walk_chain(const uint8_t *buf,
2060 bool (*fn)(uint8_t cmd,
2061 uint8_t wct, const uint16_t *vwv,
2062 uint16_t num_bytes, const uint8_t *bytes,
2063 void *private_data),
2064 void *private_data)
2066 size_t smblen = smb_len(buf);
2067 const char *smb_buf = smb_base(buf);
2068 uint8_t cmd, chain_cmd;
2069 uint8_t wct;
2070 const uint16_t *vwv;
2071 uint16_t num_bytes;
2072 const uint8_t *bytes;
2074 cmd = CVAL(buf, smb_com);
2075 wct = CVAL(buf, smb_wct);
2076 vwv = (const uint16_t *)(buf + smb_vwv);
2077 num_bytes = smb_buflen(buf);
2078 bytes = (uint8_t *)smb_buf_const(buf);
2080 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2081 return false;
2084 if (!is_andx_req(cmd)) {
2085 return true;
2087 if (wct < 2) {
2088 return false;
2091 chain_cmd = CVAL(vwv, 0);
2093 while (chain_cmd != 0xff) {
2094 uint32_t chain_offset; /* uint32_t to avoid overflow */
2095 size_t length_needed;
2096 ptrdiff_t vwv_offset;
2098 chain_offset = SVAL(vwv+1, 0);
2101 * Check if the client tries to fool us. The chain
2102 * offset needs to point beyond the current request in
2103 * the chain, it needs to strictly grow. Otherwise we
2104 * might be tricked into an endless loop always
2105 * processing the same request over and over again. We
2106 * used to assume that vwv and the byte buffer array
2107 * in a chain are always attached, but OS/2 the
2108 * Write&X/Read&X chain puts the Read&X vwv array
2109 * right behind the Write&X vwv chain. The Write&X bcc
2110 * array is put behind the Read&X vwv array. So now we
2111 * check whether the chain offset points strictly
2112 * behind the previous vwv array. req->buf points
2113 * right after the vwv array of the previous
2114 * request. See
2115 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2116 * more information.
2119 vwv_offset = ((const char *)vwv - smb_buf);
2120 if (chain_offset <= vwv_offset) {
2121 return false;
2125 * Next check: Make sure the chain offset does not
2126 * point beyond the overall smb request length.
2129 length_needed = chain_offset+1; /* wct */
2130 if (length_needed > smblen) {
2131 return false;
2135 * Now comes the pointer magic. Goal here is to set up
2136 * vwv and buf correctly again. The chain offset (the
2137 * former vwv[1]) points at the new wct field.
2140 wct = CVAL(smb_buf, chain_offset);
2142 if (is_andx_req(chain_cmd) && (wct < 2)) {
2143 return false;
2147 * Next consistency check: Make the new vwv array fits
2148 * in the overall smb request.
2151 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2152 if (length_needed > smblen) {
2153 return false;
2155 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2158 * Now grab the new byte buffer....
2161 num_bytes = SVAL(vwv+wct, 0);
2164 * .. and check that it fits.
2167 length_needed += num_bytes;
2168 if (length_needed > smblen) {
2169 return false;
2171 bytes = (const uint8_t *)(vwv+wct+1);
2173 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2174 return false;
2177 if (!is_andx_req(chain_cmd)) {
2178 return true;
2180 chain_cmd = CVAL(vwv, 0);
2182 return true;
2185 static bool smb1_chain_length_cb(uint8_t cmd,
2186 uint8_t wct, const uint16_t *vwv,
2187 uint16_t num_bytes, const uint8_t *bytes,
2188 void *private_data)
2190 unsigned *count = (unsigned *)private_data;
2191 *count += 1;
2192 return true;
2195 unsigned smb1_chain_length(const uint8_t *buf)
2197 unsigned count = 0;
2199 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2200 return 0;
2202 return count;
2205 struct smb1_parse_chain_state {
2206 TALLOC_CTX *mem_ctx;
2207 const uint8_t *buf;
2208 struct smbd_server_connection *sconn;
2209 bool encrypted;
2210 uint32_t seqnum;
2212 struct smb_request **reqs;
2213 unsigned num_reqs;
2216 static bool smb1_parse_chain_cb(uint8_t cmd,
2217 uint8_t wct, const uint16_t *vwv,
2218 uint16_t num_bytes, const uint8_t *bytes,
2219 void *private_data)
2221 struct smb1_parse_chain_state *state =
2222 (struct smb1_parse_chain_state *)private_data;
2223 struct smb_request **reqs;
2224 struct smb_request *req;
2225 bool ok;
2227 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2228 struct smb_request *, state->num_reqs+1);
2229 if (reqs == NULL) {
2230 return false;
2232 state->reqs = reqs;
2234 req = talloc(reqs, struct smb_request);
2235 if (req == NULL) {
2236 return false;
2239 ok = init_smb_request(req, state->sconn, state->buf, 0,
2240 state->encrypted, state->seqnum);
2241 if (!ok) {
2242 return false;
2244 req->cmd = cmd;
2245 req->wct = wct;
2246 req->vwv = vwv;
2247 req->buflen = num_bytes;
2248 req->buf = bytes;
2250 reqs[state->num_reqs] = req;
2251 state->num_reqs += 1;
2252 return true;
2255 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2256 struct smbd_server_connection *sconn,
2257 bool encrypted, uint32_t seqnum,
2258 struct smb_request ***reqs, unsigned *num_reqs)
2260 struct smb1_parse_chain_state state;
2261 unsigned i;
2263 state.mem_ctx = mem_ctx;
2264 state.buf = buf;
2265 state.sconn = sconn;
2266 state.encrypted = encrypted;
2267 state.seqnum = seqnum;
2268 state.reqs = NULL;
2269 state.num_reqs = 0;
2271 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2272 TALLOC_FREE(state.reqs);
2273 return false;
2275 for (i=0; i<state.num_reqs; i++) {
2276 state.reqs[i]->chain = state.reqs;
2278 *reqs = state.reqs;
2279 *num_reqs = state.num_reqs;
2280 return true;
2283 /****************************************************************************
2284 Check if services need reloading.
2285 ****************************************************************************/
2287 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2290 if (last_smb_conf_reload_time == 0) {
2291 last_smb_conf_reload_time = t;
2294 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2295 reload_services(sconn, conn_snum_used, true);
2296 last_smb_conf_reload_time = t;
2300 static bool fd_is_readable(int fd)
2302 int ret, revents;
2304 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2306 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2310 static void smbd_server_connection_write_handler(
2311 struct smbd_server_connection *sconn)
2313 /* TODO: make write nonblocking */
2316 static void smbd_server_connection_read_handler(
2317 struct smbd_server_connection *sconn, int fd)
2319 uint8_t *inbuf = NULL;
2320 size_t inbuf_len = 0;
2321 size_t unread_bytes = 0;
2322 bool encrypted = false;
2323 TALLOC_CTX *mem_ctx = talloc_tos();
2324 NTSTATUS status;
2325 uint32_t seqnum;
2327 bool from_client;
2329 if (lp_async_smb_echo_handler()
2330 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2332 * This is the super-ugly hack to prefer the packets
2333 * forwarded by the echo handler over the ones by the
2334 * client directly
2336 fd = sconn->smb1.echo_handler.trusted_fd;
2339 from_client = (sconn->sock == fd);
2341 if (from_client) {
2342 smbd_lock_socket(sconn);
2344 if (!fd_is_readable(fd)) {
2345 DEBUG(10,("the echo listener was faster\n"));
2346 smbd_unlock_socket(sconn);
2347 return;
2351 /* TODO: make this completely nonblocking */
2352 status = receive_smb_talloc(mem_ctx, sconn, fd,
2353 (char **)(void *)&inbuf,
2354 0, /* timeout */
2355 &unread_bytes,
2356 &encrypted,
2357 &inbuf_len, &seqnum,
2358 false /* trusted channel */);
2360 if (from_client) {
2361 smbd_unlock_socket(sconn);
2364 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2365 goto process;
2367 if (NT_STATUS_IS_ERR(status)) {
2368 exit_server_cleanly("failed to receive smb request");
2370 if (!NT_STATUS_IS_OK(status)) {
2371 return;
2374 process:
2375 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2376 seqnum, encrypted, NULL);
2379 static void smbd_server_connection_handler(struct event_context *ev,
2380 struct fd_event *fde,
2381 uint16_t flags,
2382 void *private_data)
2384 struct smbd_server_connection *conn = talloc_get_type(private_data,
2385 struct smbd_server_connection);
2387 if (flags & EVENT_FD_WRITE) {
2388 smbd_server_connection_write_handler(conn);
2389 return;
2391 if (flags & EVENT_FD_READ) {
2392 smbd_server_connection_read_handler(conn, conn->sock);
2393 return;
2397 static void smbd_server_echo_handler(struct event_context *ev,
2398 struct fd_event *fde,
2399 uint16_t flags,
2400 void *private_data)
2402 struct smbd_server_connection *conn = talloc_get_type(private_data,
2403 struct smbd_server_connection);
2405 if (flags & EVENT_FD_WRITE) {
2406 smbd_server_connection_write_handler(conn);
2407 return;
2409 if (flags & EVENT_FD_READ) {
2410 smbd_server_connection_read_handler(
2411 conn, conn->smb1.echo_handler.trusted_fd);
2412 return;
2416 #ifdef CLUSTER_SUPPORT
2417 /****************************************************************************
2418 received when we should release a specific IP
2419 ****************************************************************************/
2420 static void release_ip(const char *ip, void *priv)
2422 const char *addr = (const char *)priv;
2423 const char *p = addr;
2425 if (strncmp("::ffff:", addr, 7) == 0) {
2426 p = addr + 7;
2429 DEBUG(10, ("Got release IP message for %s, "
2430 "our address is %s\n", ip, p));
2432 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2433 /* we can't afford to do a clean exit - that involves
2434 database writes, which would potentially mean we
2435 are still running after the failover has finished -
2436 we have to get rid of this process ID straight
2437 away */
2438 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2439 ip));
2440 /* note we must exit with non-zero status so the unclean handler gets
2441 called in the parent, so that the brl database is tickled */
2442 _exit(1);
2446 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2447 struct sockaddr_storage *client)
2449 socklen_t length;
2450 length = sizeof(*server);
2451 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2452 return -1;
2454 length = sizeof(*client);
2455 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2456 return -1;
2458 return 0;
2460 #endif
2463 * Send keepalive packets to our client
2465 static bool keepalive_fn(const struct timeval *now, void *private_data)
2467 struct smbd_server_connection *sconn = talloc_get_type_abort(
2468 private_data, struct smbd_server_connection);
2469 bool ret;
2471 if (sconn->using_smb2) {
2472 /* Don't do keepalives on an SMB2 connection. */
2473 return false;
2476 smbd_lock_socket(sconn);
2477 ret = send_keepalive(sconn->sock);
2478 smbd_unlock_socket(sconn);
2480 if (!ret) {
2481 char addr[INET6_ADDRSTRLEN];
2483 * Try and give an error message saying what
2484 * client failed.
2486 DEBUG(0, ("send_keepalive failed for client %s. "
2487 "Error %s - exiting\n",
2488 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2489 strerror(errno)));
2490 return False;
2492 return True;
2496 * Do the recurring check if we're idle
2498 static bool deadtime_fn(const struct timeval *now, void *private_data)
2500 struct smbd_server_connection *sconn =
2501 (struct smbd_server_connection *)private_data;
2503 if ((conn_num_open(sconn) == 0)
2504 || (conn_idle_all(sconn, now->tv_sec))) {
2505 DEBUG( 2, ( "Closing idle connection\n" ) );
2506 messaging_send(sconn->msg_ctx,
2507 messaging_server_id(sconn->msg_ctx),
2508 MSG_SHUTDOWN, &data_blob_null);
2509 return False;
2512 return True;
2516 * Do the recurring log file and smb.conf reload checks.
2519 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2521 struct smbd_server_connection *sconn = talloc_get_type_abort(
2522 private_data, struct smbd_server_connection);
2524 DEBUG(5, ("housekeeping\n"));
2526 change_to_root_user();
2528 /* update printer queue caches if necessary */
2529 update_monitored_printq_cache(sconn->msg_ctx);
2531 /* check if we need to reload services */
2532 check_reload(sconn, time_mono(NULL));
2534 /* Change machine password if neccessary. */
2535 attempt_machine_password_change();
2538 * Force a log file check.
2540 force_check_log_size();
2541 check_log_size();
2542 return true;
2546 * Read an smb packet in the echo handler child, giving the parent
2547 * smbd one second to react once the socket becomes readable.
2550 struct smbd_echo_read_state {
2551 struct tevent_context *ev;
2552 struct smbd_server_connection *sconn;
2554 char *buf;
2555 size_t buflen;
2556 uint32_t seqnum;
2559 static void smbd_echo_read_readable(struct tevent_req *subreq);
2560 static void smbd_echo_read_waited(struct tevent_req *subreq);
2562 static struct tevent_req *smbd_echo_read_send(
2563 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2564 struct smbd_server_connection *sconn)
2566 struct tevent_req *req, *subreq;
2567 struct smbd_echo_read_state *state;
2569 req = tevent_req_create(mem_ctx, &state,
2570 struct smbd_echo_read_state);
2571 if (req == NULL) {
2572 return NULL;
2574 state->ev = ev;
2575 state->sconn = sconn;
2577 subreq = wait_for_read_send(state, ev, sconn->sock);
2578 if (tevent_req_nomem(subreq, req)) {
2579 return tevent_req_post(req, ev);
2581 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2582 return req;
2585 static void smbd_echo_read_readable(struct tevent_req *subreq)
2587 struct tevent_req *req = tevent_req_callback_data(
2588 subreq, struct tevent_req);
2589 struct smbd_echo_read_state *state = tevent_req_data(
2590 req, struct smbd_echo_read_state);
2591 bool ok;
2592 int err;
2594 ok = wait_for_read_recv(subreq, &err);
2595 TALLOC_FREE(subreq);
2596 if (!ok) {
2597 tevent_req_nterror(req, map_nt_error_from_unix(err));
2598 return;
2602 * Give the parent smbd one second to step in
2605 subreq = tevent_wakeup_send(
2606 state, state->ev, timeval_current_ofs(1, 0));
2607 if (tevent_req_nomem(subreq, req)) {
2608 return;
2610 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2613 static void smbd_echo_read_waited(struct tevent_req *subreq)
2615 struct tevent_req *req = tevent_req_callback_data(
2616 subreq, struct tevent_req);
2617 struct smbd_echo_read_state *state = tevent_req_data(
2618 req, struct smbd_echo_read_state);
2619 struct smbd_server_connection *sconn = state->sconn;
2620 bool ok;
2621 NTSTATUS status;
2622 size_t unread = 0;
2623 bool encrypted;
2625 ok = tevent_wakeup_recv(subreq);
2626 TALLOC_FREE(subreq);
2627 if (!ok) {
2628 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2629 return;
2632 ok = smbd_lock_socket_internal(sconn);
2633 if (!ok) {
2634 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2635 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2636 return;
2639 if (!fd_is_readable(sconn->sock)) {
2640 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2641 (int)getpid()));
2643 ok = smbd_unlock_socket_internal(sconn);
2644 if (!ok) {
2645 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2646 DEBUG(1, ("%s: failed to unlock socket\n",
2647 __location__));
2648 return;
2651 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2652 if (tevent_req_nomem(subreq, req)) {
2653 return;
2655 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2656 return;
2659 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2660 0 /* timeout */,
2661 &unread,
2662 &encrypted,
2663 &state->buflen,
2664 &state->seqnum,
2665 false /* trusted_channel*/);
2667 if (tevent_req_nterror(req, status)) {
2668 tevent_req_nterror(req, status);
2669 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2670 (int)getpid(), nt_errstr(status)));
2671 return;
2674 ok = smbd_unlock_socket_internal(sconn);
2675 if (!ok) {
2676 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2677 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2678 return;
2680 tevent_req_done(req);
2683 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2684 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2686 struct smbd_echo_read_state *state = tevent_req_data(
2687 req, struct smbd_echo_read_state);
2688 NTSTATUS status;
2690 if (tevent_req_is_nterror(req, &status)) {
2691 return status;
2693 *pbuf = talloc_move(mem_ctx, &state->buf);
2694 *pbuflen = state->buflen;
2695 *pseqnum = state->seqnum;
2696 return NT_STATUS_OK;
2699 struct smbd_echo_state {
2700 struct tevent_context *ev;
2701 struct iovec *pending;
2702 struct smbd_server_connection *sconn;
2703 int parent_pipe;
2705 struct tevent_fd *parent_fde;
2707 struct tevent_req *write_req;
2710 static void smbd_echo_writer_done(struct tevent_req *req);
2712 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2714 int num_pending;
2716 if (state->write_req != NULL) {
2717 return;
2720 num_pending = talloc_array_length(state->pending);
2721 if (num_pending == 0) {
2722 return;
2725 state->write_req = writev_send(state, state->ev, NULL,
2726 state->parent_pipe, false,
2727 state->pending, num_pending);
2728 if (state->write_req == NULL) {
2729 DEBUG(1, ("writev_send failed\n"));
2730 exit(1);
2733 talloc_steal(state->write_req, state->pending);
2734 state->pending = NULL;
2736 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2737 state);
2740 static void smbd_echo_writer_done(struct tevent_req *req)
2742 struct smbd_echo_state *state = tevent_req_callback_data(
2743 req, struct smbd_echo_state);
2744 ssize_t written;
2745 int err;
2747 written = writev_recv(req, &err);
2748 TALLOC_FREE(req);
2749 state->write_req = NULL;
2750 if (written == -1) {
2751 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2752 exit(1);
2754 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2755 smbd_echo_activate_writer(state);
2758 static bool smbd_echo_reply(struct smbd_echo_state *state,
2759 uint8_t *inbuf, size_t inbuf_len,
2760 uint32_t seqnum)
2762 struct smb_request req;
2763 uint16_t num_replies;
2764 char *outbuf;
2765 bool ok;
2767 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2768 DEBUG(10, ("Got netbios keepalive\n"));
2770 * Just swallow it
2772 return true;
2775 if (inbuf_len < smb_size) {
2776 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2777 return false;
2779 if (!valid_smb_header(state->sconn, inbuf)) {
2780 DEBUG(10, ("Got invalid SMB header\n"));
2781 return false;
2784 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2785 seqnum)) {
2786 return false;
2788 req.inbuf = inbuf;
2790 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2791 smb_messages[req.cmd].name
2792 ? smb_messages[req.cmd].name : "unknown"));
2794 if (req.cmd != SMBecho) {
2795 return false;
2797 if (req.wct < 1) {
2798 return false;
2801 num_replies = SVAL(req.vwv+0, 0);
2802 if (num_replies != 1) {
2803 /* Not a Windows "Hey, you're still there?" request */
2804 return false;
2807 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2808 1, req.buflen)) {
2809 DEBUG(10, ("create_outbuf failed\n"));
2810 return false;
2812 req.outbuf = (uint8_t *)outbuf;
2814 SSVAL(req.outbuf, smb_vwv0, num_replies);
2816 if (req.buflen > 0) {
2817 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2820 ok = srv_send_smb(req.sconn,
2821 (char *)outbuf,
2822 true, seqnum+1,
2823 false, &req.pcd);
2824 TALLOC_FREE(outbuf);
2825 if (!ok) {
2826 exit(1);
2829 return true;
2832 static void smbd_echo_exit(struct tevent_context *ev,
2833 struct tevent_fd *fde, uint16_t flags,
2834 void *private_data)
2836 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2837 exit(0);
2840 static void smbd_echo_got_packet(struct tevent_req *req);
2842 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2843 int parent_pipe)
2845 struct smbd_echo_state *state;
2846 struct tevent_req *read_req;
2848 state = talloc_zero(sconn, struct smbd_echo_state);
2849 if (state == NULL) {
2850 DEBUG(1, ("talloc failed\n"));
2851 return;
2853 state->sconn = sconn;
2854 state->parent_pipe = parent_pipe;
2855 state->ev = s3_tevent_context_init(state);
2856 if (state->ev == NULL) {
2857 DEBUG(1, ("tevent_context_init failed\n"));
2858 TALLOC_FREE(state);
2859 return;
2861 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2862 TEVENT_FD_READ, smbd_echo_exit,
2863 state);
2864 if (state->parent_fde == NULL) {
2865 DEBUG(1, ("tevent_add_fd failed\n"));
2866 TALLOC_FREE(state);
2867 return;
2870 read_req = smbd_echo_read_send(state, state->ev, sconn);
2871 if (read_req == NULL) {
2872 DEBUG(1, ("smbd_echo_read_send failed\n"));
2873 TALLOC_FREE(state);
2874 return;
2876 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2878 while (true) {
2879 if (tevent_loop_once(state->ev) == -1) {
2880 DEBUG(1, ("tevent_loop_once failed: %s\n",
2881 strerror(errno)));
2882 break;
2885 TALLOC_FREE(state);
2888 static void smbd_echo_got_packet(struct tevent_req *req)
2890 struct smbd_echo_state *state = tevent_req_callback_data(
2891 req, struct smbd_echo_state);
2892 NTSTATUS status;
2893 char *buf = NULL;
2894 size_t buflen = 0;
2895 uint32_t seqnum = 0;
2896 bool reply;
2898 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2899 TALLOC_FREE(req);
2900 if (!NT_STATUS_IS_OK(status)) {
2901 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2902 nt_errstr(status)));
2903 exit(1);
2906 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2907 if (!reply) {
2908 size_t num_pending;
2909 struct iovec *tmp;
2910 struct iovec *iov;
2912 num_pending = talloc_array_length(state->pending);
2913 tmp = talloc_realloc(state, state->pending, struct iovec,
2914 num_pending+1);
2915 if (tmp == NULL) {
2916 DEBUG(1, ("talloc_realloc failed\n"));
2917 exit(1);
2919 state->pending = tmp;
2921 if (buflen >= smb_size) {
2923 * place the seqnum in the packet so that the main process
2924 * can reply with signing
2926 SIVAL(buf, smb_ss_field, seqnum);
2927 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2930 iov = &state->pending[num_pending];
2931 iov->iov_base = buf;
2932 iov->iov_len = buflen;
2934 DEBUG(10,("echo_handler[%d]: forward to main\n",
2935 (int)getpid()));
2936 smbd_echo_activate_writer(state);
2939 req = smbd_echo_read_send(state, state->ev, state->sconn);
2940 if (req == NULL) {
2941 DEBUG(1, ("smbd_echo_read_send failed\n"));
2942 exit(1);
2944 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2949 * Handle SMBecho requests in a forked child process
2951 bool fork_echo_handler(struct smbd_server_connection *sconn)
2953 int listener_pipe[2];
2954 int res;
2955 pid_t child;
2957 res = pipe(listener_pipe);
2958 if (res == -1) {
2959 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2960 return false;
2962 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2963 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2964 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2965 goto fail;
2968 child = fork();
2969 if (child == 0) {
2970 NTSTATUS status;
2972 close(listener_pipe[0]);
2973 set_blocking(listener_pipe[1], false);
2975 status = reinit_after_fork(sconn->msg_ctx,
2976 sconn->ev_ctx,
2977 false);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 DEBUG(1, ("reinit_after_fork failed: %s\n",
2980 nt_errstr(status)));
2981 exit(1);
2983 smbd_echo_loop(sconn, listener_pipe[1]);
2984 exit(0);
2986 close(listener_pipe[1]);
2987 listener_pipe[1] = -1;
2988 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2990 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
2993 * Without smb signing this is the same as the normal smbd
2994 * listener. This needs to change once signing comes in.
2996 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2997 sconn,
2998 sconn->smb1.echo_handler.trusted_fd,
2999 TEVENT_FD_READ,
3000 smbd_server_echo_handler,
3001 sconn);
3002 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3003 DEBUG(1, ("event_add_fd failed\n"));
3004 goto fail;
3007 return true;
3009 fail:
3010 if (listener_pipe[0] != -1) {
3011 close(listener_pipe[0]);
3013 if (listener_pipe[1] != -1) {
3014 close(listener_pipe[1]);
3016 sconn->smb1.echo_handler.trusted_fd = -1;
3017 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3018 close(sconn->smb1.echo_handler.socket_lock_fd);
3020 sconn->smb1.echo_handler.trusted_fd = -1;
3021 sconn->smb1.echo_handler.socket_lock_fd = -1;
3022 return false;
3025 #if CLUSTER_SUPPORT
3027 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
3028 struct sockaddr_storage *srv,
3029 struct sockaddr_storage *clnt)
3031 struct ctdbd_connection *cconn;
3032 char tmp_addr[INET6_ADDRSTRLEN];
3033 char *addr;
3035 cconn = messaging_ctdbd_connection();
3036 if (cconn == NULL) {
3037 return NT_STATUS_NO_MEMORY;
3040 if (client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr)) == NULL) {
3041 return NT_STATUS_NO_MEMORY;
3043 addr = talloc_strdup(cconn, tmp_addr);
3044 if (addr == NULL) {
3045 return NT_STATUS_NO_MEMORY;
3047 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
3050 #endif
3052 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3054 while (user) {
3055 if (user->session_info &&
3056 (user->session_info->unix_token->uid == uid)) {
3057 return true;
3059 user = user->next;
3061 return false;
3064 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3066 while (user) {
3067 if (user->session_info != NULL) {
3068 int i;
3069 struct security_unix_token *utok;
3071 utok = user->session_info->unix_token;
3072 if (utok->gid == gid) {
3073 return true;
3075 for(i=0; i<utok->ngroups; i++) {
3076 if (utok->groups[i] == gid) {
3077 return true;
3081 user = user->next;
3083 return false;
3086 static bool sid_in_use(const struct user_struct *user,
3087 const struct dom_sid *psid)
3089 while (user) {
3090 struct security_token *tok;
3092 if (user->session_info == NULL) {
3093 continue;
3095 tok = user->session_info->security_token;
3096 if (tok == NULL) {
3098 * Not sure session_info->security_token can
3099 * ever be NULL. This check might be not
3100 * necessary.
3102 continue;
3104 if (security_token_has_sid(tok, psid)) {
3105 return true;
3107 user = user->next;
3109 return false;
3112 static bool id_in_use(const struct user_struct *user,
3113 const struct id_cache_ref *id)
3115 switch(id->type) {
3116 case UID:
3117 return uid_in_use(user, id->id.uid);
3118 case GID:
3119 return gid_in_use(user, id->id.gid);
3120 case SID:
3121 return sid_in_use(user, &id->id.sid);
3122 default:
3123 break;
3125 return false;
3128 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3129 void *private_data,
3130 uint32_t msg_type,
3131 struct server_id server_id,
3132 DATA_BLOB* data)
3134 const char *msg = (data && data->data)
3135 ? (const char *)data->data : "<NULL>";
3136 struct id_cache_ref id;
3137 struct smbd_server_connection *sconn =
3138 talloc_get_type_abort(private_data,
3139 struct smbd_server_connection);
3141 if (!id_cache_ref_parse(msg, &id)) {
3142 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3143 return;
3146 if (id_in_use(sconn->users, &id)) {
3147 exit_server_cleanly(msg);
3149 id_cache_delete_from_cache(&id);
3152 /****************************************************************************
3153 Process commands from the client
3154 ****************************************************************************/
3156 void smbd_process(struct tevent_context *ev_ctx,
3157 struct smbd_server_connection *sconn)
3159 TALLOC_CTX *frame = talloc_stackframe();
3160 struct sockaddr_storage ss;
3161 struct sockaddr *sa = NULL;
3162 socklen_t sa_socklen;
3163 struct tsocket_address *local_address = NULL;
3164 struct tsocket_address *remote_address = NULL;
3165 const char *locaddr = NULL;
3166 const char *remaddr = NULL;
3167 char *rhost;
3168 int ret;
3170 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3172 * We're not making the decision here,
3173 * we're just allowing the client
3174 * to decide between SMB1 and SMB2
3175 * with the first negprot
3176 * packet.
3178 sconn->using_smb2 = true;
3181 /* Ensure child is set to blocking mode */
3182 set_blocking(sconn->sock,True);
3184 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3185 set_socket_options(sconn->sock, lp_socket_options());
3187 sa = (struct sockaddr *)(void *)&ss;
3188 sa_socklen = sizeof(ss);
3189 ret = getpeername(sconn->sock, sa, &sa_socklen);
3190 if (ret != 0) {
3191 int level = (errno == ENOTCONN)?2:0;
3192 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3193 exit_server_cleanly("getpeername() failed.\n");
3195 ret = tsocket_address_bsd_from_sockaddr(sconn,
3196 sa, sa_socklen,
3197 &remote_address);
3198 if (ret != 0) {
3199 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3200 __location__, strerror(errno)));
3201 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3204 sa = (struct sockaddr *)(void *)&ss;
3205 sa_socklen = sizeof(ss);
3206 ret = getsockname(sconn->sock, sa, &sa_socklen);
3207 if (ret != 0) {
3208 int level = (errno == ENOTCONN)?2:0;
3209 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3210 exit_server_cleanly("getsockname() failed.\n");
3212 ret = tsocket_address_bsd_from_sockaddr(sconn,
3213 sa, sa_socklen,
3214 &local_address);
3215 if (ret != 0) {
3216 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3217 __location__, strerror(errno)));
3218 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3221 sconn->local_address = local_address;
3222 sconn->remote_address = remote_address;
3224 if (tsocket_address_is_inet(local_address, "ip")) {
3225 locaddr = tsocket_address_inet_addr_string(
3226 sconn->local_address,
3227 talloc_tos());
3228 if (locaddr == NULL) {
3229 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3230 __location__, strerror(errno)));
3231 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3233 } else {
3234 locaddr = "0.0.0.0";
3237 if (tsocket_address_is_inet(remote_address, "ip")) {
3238 remaddr = tsocket_address_inet_addr_string(
3239 sconn->remote_address,
3240 talloc_tos());
3241 if (remaddr == NULL) {
3242 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3243 __location__, strerror(errno)));
3244 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3246 } else {
3247 remaddr = "0.0.0.0";
3250 /* this is needed so that we get decent entries
3251 in smbstatus for port 445 connects */
3252 set_remote_machine_name(remaddr, false);
3253 reload_services(sconn, conn_snum_used, true);
3256 * Before the first packet, check the global hosts allow/ hosts deny
3257 * parameters before doing any parsing of packets passed to us by the
3258 * client. This prevents attacks on our parsing code from hosts not in
3259 * the hosts allow list.
3262 ret = get_remote_hostname(remote_address,
3263 &rhost,
3264 talloc_tos());
3265 if (ret < 0) {
3266 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3267 __location__, strerror(errno)));
3268 exit_server_cleanly("get_remote_hostname failed.\n");
3270 if (strequal(rhost, "UNKNOWN")) {
3271 rhost = talloc_strdup(talloc_tos(), remaddr);
3273 sconn->remote_hostname = talloc_move(sconn, &rhost);
3275 sub_set_socket_ids(remaddr,
3276 sconn->remote_hostname,
3277 locaddr);
3279 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3280 sconn->remote_hostname,
3281 remaddr)) {
3283 * send a negative session response "not listening on calling
3284 * name"
3286 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3287 DEBUG( 1, ("Connection denied from %s to %s\n",
3288 tsocket_address_string(remote_address, talloc_tos()),
3289 tsocket_address_string(local_address, talloc_tos())));
3290 (void)srv_send_smb(sconn,(char *)buf, false,
3291 0, false, NULL);
3292 exit_server_cleanly("connection denied");
3295 DEBUG(10, ("Connection allowed from %s to %s\n",
3296 tsocket_address_string(remote_address, talloc_tos()),
3297 tsocket_address_string(local_address, talloc_tos())));
3299 init_modules();
3301 smb_perfcount_init();
3303 if (!init_account_policy()) {
3304 exit_server("Could not open account policy tdb.\n");
3307 if (*lp_rootdir()) {
3308 if (chroot(lp_rootdir()) != 0) {
3309 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3310 exit_server("Failed to chroot()");
3312 if (chdir("/") == -1) {
3313 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3314 exit_server("Failed to chroot()");
3316 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3319 if (!srv_init_signing(sconn)) {
3320 exit_server("Failed to init smb_signing");
3323 /* Setup oplocks */
3324 if (!init_oplocks(sconn))
3325 exit_server("Failed to init oplocks");
3327 /* register our message handlers */
3328 messaging_register(sconn->msg_ctx, sconn,
3329 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3330 messaging_register(sconn->msg_ctx, sconn,
3331 MSG_SMB_CLOSE_FILE, msg_close_file);
3332 messaging_register(sconn->msg_ctx, sconn,
3333 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3335 id_cache_register_msgs(sconn->msg_ctx);
3336 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3337 messaging_register(sconn->msg_ctx, sconn,
3338 ID_CACHE_KILL, smbd_id_cache_kill);
3340 messaging_deregister(sconn->msg_ctx,
3341 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3342 messaging_register(sconn->msg_ctx, sconn,
3343 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3346 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3347 * MSGs to all child processes
3349 messaging_deregister(sconn->msg_ctx,
3350 MSG_DEBUG, NULL);
3351 messaging_register(sconn->msg_ctx, NULL,
3352 MSG_DEBUG, debug_message);
3354 if ((lp_keepalive() != 0)
3355 && !(event_add_idle(ev_ctx, NULL,
3356 timeval_set(lp_keepalive(), 0),
3357 "keepalive", keepalive_fn,
3358 sconn))) {
3359 DEBUG(0, ("Could not add keepalive event\n"));
3360 exit(1);
3363 if (!(event_add_idle(ev_ctx, NULL,
3364 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3365 "deadtime", deadtime_fn, sconn))) {
3366 DEBUG(0, ("Could not add deadtime event\n"));
3367 exit(1);
3370 if (!(event_add_idle(ev_ctx, NULL,
3371 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3372 "housekeeping", housekeeping_fn, sconn))) {
3373 DEBUG(0, ("Could not add housekeeping event\n"));
3374 exit(1);
3377 #ifdef CLUSTER_SUPPORT
3379 if (lp_clustering()) {
3381 * We need to tell ctdb about our client's TCP
3382 * connection, so that for failover ctdbd can send
3383 * tickle acks, triggering a reconnection by the
3384 * client.
3387 struct sockaddr_storage srv, clnt;
3389 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3390 NTSTATUS status;
3391 status = smbd_register_ips(sconn, &srv, &clnt);
3392 if (!NT_STATUS_IS_OK(status)) {
3393 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3394 nt_errstr(status)));
3396 } else
3398 DEBUG(0,("Unable to get tcp info for "
3399 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3400 strerror(errno)));
3404 #endif
3406 sconn->nbt.got_session = false;
3408 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3410 sconn->smb1.sessions.done_sesssetup = false;
3411 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3412 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3413 /* this holds info on user ids that are already validated for this VC */
3414 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3416 conn_init(sconn);
3417 if (!init_dptrs(sconn)) {
3418 exit_server("init_dptrs() failed");
3421 sconn->smb1.fde = event_add_fd(ev_ctx,
3422 sconn,
3423 sconn->sock,
3424 EVENT_FD_READ,
3425 smbd_server_connection_handler,
3426 sconn);
3427 if (!sconn->smb1.fde) {
3428 exit_server("failed to create smbd_server_connection fde");
3431 TALLOC_FREE(frame);
3433 while (True) {
3434 frame = talloc_stackframe_pool(8192);
3436 errno = 0;
3437 if (tevent_loop_once(ev_ctx) == -1) {
3438 if (errno != EINTR) {
3439 DEBUG(3, ("tevent_loop_once failed: %s,"
3440 " exiting\n", strerror(errno) ));
3441 break;
3445 TALLOC_FREE(frame);
3448 exit_server_cleanly(NULL);
3451 bool req_is_in_chain(struct smb_request *req)
3453 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3455 * We're right now handling a subsequent request, so we must
3456 * be in a chain
3458 return true;
3461 if (!is_andx_req(req->cmd)) {
3462 return false;
3465 if (req->wct < 2) {
3467 * Okay, an illegal request, but definitely not chained :-)
3469 return false;
3472 return (CVAL(req->vwv+0, 0) != 0xFF);