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