s4 dns: Move record lookup to dns_utils.c
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blobc44826778188f13bcaf4358cc1628e897598e310
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);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
66 bool ok;
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 return true;
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
75 return true;
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
83 SMB_F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
86 if (!ok) {
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 return false;
91 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
93 return true;
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
105 bool ok;
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 return true;
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
114 return true;
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
120 SMB_F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
123 if (!ok) {
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 return false;
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
130 return true;
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
143 Send an smb to a fd.
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
151 size_t len = 0;
152 size_t nwritten=0;
153 ssize_t ret;
154 char *buf_out = buffer;
156 smbd_lock_socket(sconn);
158 if (do_signing) {
159 /* Sign the outgoing packet if required. */
160 srv_calculate_sign_mac(sconn, buf_out, seqnum);
163 if (do_encrypt) {
164 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
165 if (!NT_STATUS_IS_OK(status)) {
166 DEBUG(0, ("send_smb: SMB encryption failed "
167 "on outgoing packet! Error %s\n",
168 nt_errstr(status) ));
169 goto out;
173 len = smb_len(buf_out) + 4;
175 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
176 if (ret <= 0) {
178 char addr[INET6_ADDRSTRLEN];
180 * Try and give an error message saying what
181 * client failed.
183 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
184 (int)sys_getpid(), (int)len,
185 get_peer_addr(sconn->sock, addr, sizeof(addr)),
186 (int)ret, strerror(errno) ));
188 srv_free_enc_buffer(sconn, buf_out);
189 goto out;
192 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
193 srv_free_enc_buffer(sconn, buf_out);
194 out:
195 SMB_PERFCOUNT_END(pcd);
197 smbd_unlock_socket(sconn);
198 return true;
201 /*******************************************************************
202 Setup the word count and byte count for a smb message.
203 ********************************************************************/
205 int srv_set_message(char *buf,
206 int num_words,
207 int num_bytes,
208 bool zero)
210 if (zero && (num_words || num_bytes)) {
211 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
213 SCVAL(buf,smb_wct,num_words);
214 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
215 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
216 return (smb_size + num_words*2 + num_bytes);
219 static bool valid_smb_header(struct smbd_server_connection *sconn,
220 const uint8_t *inbuf)
222 if (is_encrypted_packet(sconn, inbuf)) {
223 return true;
226 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
227 * but it just looks weird to call strncmp for this one.
229 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
232 /* Socket functions for smbd packet processing. */
234 static bool valid_packet_size(size_t len)
237 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
238 * of header. Don't print the error if this fits.... JRA.
241 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
242 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
243 (unsigned long)len));
244 return false;
246 return true;
249 static NTSTATUS read_packet_remainder(int fd, char *buffer,
250 unsigned int timeout, ssize_t len)
252 NTSTATUS status;
254 if (len <= 0) {
255 return NT_STATUS_OK;
258 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
259 if (!NT_STATUS_IS_OK(status)) {
260 char addr[INET6_ADDRSTRLEN];
261 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
262 "error = %s.\n",
263 get_peer_addr(fd, addr, sizeof(addr)),
264 nt_errstr(status)));
266 return status;
269 /****************************************************************************
270 Attempt a zerocopy writeX read. We know here that len > smb_size-4
271 ****************************************************************************/
274 * Unfortunately, earlier versions of smbclient/libsmbclient
275 * don't send this "standard" writeX header. I've fixed this
276 * for 3.2 but we'll use the old method with earlier versions.
277 * Windows and CIFSFS at least use this standard size. Not
278 * sure about MacOSX.
281 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
282 (2*14) + /* word count (including bcc) */ \
283 1 /* pad byte */)
285 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
286 const char lenbuf[4],
287 struct smbd_server_connection *sconn,
288 int sock,
289 char **buffer,
290 unsigned int timeout,
291 size_t *p_unread,
292 size_t *len_ret)
294 /* Size of a WRITEX call (+4 byte len). */
295 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
296 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
297 ssize_t toread;
298 NTSTATUS status;
300 memcpy(writeX_header, lenbuf, 4);
302 status = read_fd_with_timeout(
303 sock, writeX_header + 4,
304 STANDARD_WRITE_AND_X_HEADER_SIZE,
305 STANDARD_WRITE_AND_X_HEADER_SIZE,
306 timeout, NULL);
308 if (!NT_STATUS_IS_OK(status)) {
309 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
310 "error = %s.\n",
311 tsocket_address_string(sconn->remote_address,
312 talloc_tos()),
313 nt_errstr(status)));
314 return status;
318 * Ok - now try and see if this is a possible
319 * valid writeX call.
322 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
324 * If the data offset is beyond what
325 * we've read, drain the extra bytes.
327 uint16_t doff = SVAL(writeX_header,smb_vwv11);
328 ssize_t newlen;
330 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
331 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
332 if (drain_socket(sock, drain) != drain) {
333 smb_panic("receive_smb_raw_talloc_partial_read:"
334 " failed to drain pending bytes");
336 } else {
337 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
340 /* Spoof down the length and null out the bcc. */
341 set_message_bcc(writeX_header, 0);
342 newlen = smb_len(writeX_header);
344 /* Copy the header we've written. */
346 *buffer = (char *)talloc_memdup(mem_ctx,
347 writeX_header,
348 sizeof(writeX_header));
350 if (*buffer == NULL) {
351 DEBUG(0, ("Could not allocate inbuf of length %d\n",
352 (int)sizeof(writeX_header)));
353 return NT_STATUS_NO_MEMORY;
356 /* Work out the remaining bytes. */
357 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
358 *len_ret = newlen + 4;
359 return NT_STATUS_OK;
362 if (!valid_packet_size(len)) {
363 return NT_STATUS_INVALID_PARAMETER;
367 * Not a valid writeX call. Just do the standard
368 * talloc and return.
371 *buffer = talloc_array(mem_ctx, char, len+4);
373 if (*buffer == NULL) {
374 DEBUG(0, ("Could not allocate inbuf of length %d\n",
375 (int)len+4));
376 return NT_STATUS_NO_MEMORY;
379 /* Copy in what we already read. */
380 memcpy(*buffer,
381 writeX_header,
382 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
383 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
385 if(toread > 0) {
386 status = read_packet_remainder(
387 sock,
388 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
389 timeout, toread);
391 if (!NT_STATUS_IS_OK(status)) {
392 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
393 nt_errstr(status)));
394 return status;
398 *len_ret = len + 4;
399 return NT_STATUS_OK;
402 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
403 struct smbd_server_connection *sconn,
404 int sock,
405 char **buffer, unsigned int timeout,
406 size_t *p_unread, size_t *plen)
408 char lenbuf[4];
409 size_t len;
410 int min_recv_size = lp_min_receive_file_size();
411 NTSTATUS status;
413 *p_unread = 0;
415 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
416 &len);
417 if (!NT_STATUS_IS_OK(status)) {
418 return status;
421 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
422 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
423 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
424 !srv_is_signing_active(sconn) &&
425 sconn->smb1.echo_handler.trusted_fde == NULL) {
427 return receive_smb_raw_talloc_partial_read(
428 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
429 p_unread, plen);
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * The +4 here can't wrap, we've checked the length above already.
440 *buffer = talloc_array(mem_ctx, char, len+4);
442 if (*buffer == NULL) {
443 DEBUG(0, ("Could not allocate inbuf of length %d\n",
444 (int)len+4));
445 return NT_STATUS_NO_MEMORY;
448 memcpy(*buffer, lenbuf, sizeof(lenbuf));
450 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
451 if (!NT_STATUS_IS_OK(status)) {
452 return status;
455 *plen = len + 4;
456 return NT_STATUS_OK;
459 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
460 struct smbd_server_connection *sconn,
461 int sock,
462 char **buffer, unsigned int timeout,
463 size_t *p_unread, bool *p_encrypted,
464 size_t *p_len,
465 uint32_t *seqnum,
466 bool trusted_channel)
468 size_t len = 0;
469 NTSTATUS status;
471 *p_encrypted = false;
473 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
474 p_unread, &len);
475 if (!NT_STATUS_IS_OK(status)) {
476 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
477 ("receive_smb_raw_talloc failed for client %s "
478 "read error = %s.\n",
479 tsocket_address_string(sconn->remote_address,
480 talloc_tos()),
481 nt_errstr(status)) );
482 return status;
485 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
486 status = srv_decrypt_buffer(sconn, *buffer);
487 if (!NT_STATUS_IS_OK(status)) {
488 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
489 "incoming packet! Error %s\n",
490 nt_errstr(status) ));
491 return status;
493 *p_encrypted = true;
496 /* Check the incoming SMB signature. */
497 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
498 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
499 "incoming packet!\n"));
500 return NT_STATUS_INVALID_NETWORK_RESPONSE;
503 *p_len = len;
504 return NT_STATUS_OK;
508 * Initialize a struct smb_request from an inbuf
511 static bool init_smb_request(struct smb_request *req,
512 struct smbd_server_connection *sconn,
513 const uint8 *inbuf,
514 size_t unread_bytes, bool encrypted,
515 uint32_t seqnum)
517 size_t req_size = smb_len(inbuf) + 4;
518 /* Ensure we have at least smb_size bytes. */
519 if (req_size < smb_size) {
520 DEBUG(0,("init_smb_request: invalid request size %u\n",
521 (unsigned int)req_size ));
522 return false;
524 req->cmd = CVAL(inbuf, smb_com);
525 req->flags2 = SVAL(inbuf, smb_flg2);
526 req->smbpid = SVAL(inbuf, smb_pid);
527 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
528 req->seqnum = seqnum;
529 req->vuid = SVAL(inbuf, smb_uid);
530 req->tid = SVAL(inbuf, smb_tid);
531 req->wct = CVAL(inbuf, smb_wct);
532 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
533 req->buflen = smb_buflen(inbuf);
534 req->buf = (const uint8_t *)smb_buf_const(inbuf);
535 req->unread_bytes = unread_bytes;
536 req->encrypted = encrypted;
537 req->sconn = sconn;
538 req->conn = conn_find(sconn,req->tid);
539 req->chain_fsp = NULL;
540 req->chain_outbuf = NULL;
541 req->done = false;
542 req->smb2req = NULL;
543 smb_init_perfcount_data(&req->pcd);
545 /* Ensure we have at least wct words and 2 bytes of bcc. */
546 if (smb_size + req->wct*2 > req_size) {
547 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
548 (unsigned int)req->wct,
549 (unsigned int)req_size));
550 return false;
552 /* Ensure bcc is correct. */
553 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
554 DEBUG(0,("init_smb_request: invalid bcc number %u "
555 "(wct = %u, size %u)\n",
556 (unsigned int)req->buflen,
557 (unsigned int)req->wct,
558 (unsigned int)req_size));
559 return false;
562 req->outbuf = NULL;
563 return true;
566 static void process_smb(struct smbd_server_connection *conn,
567 uint8_t *inbuf, size_t nread, size_t unread_bytes,
568 uint32_t seqnum, bool encrypted,
569 struct smb_perfcount_data *deferred_pcd);
571 static void smbd_deferred_open_timer(struct event_context *ev,
572 struct timed_event *te,
573 struct timeval _tval,
574 void *private_data)
576 struct pending_message_list *msg = talloc_get_type(private_data,
577 struct pending_message_list);
578 struct smbd_server_connection *sconn = msg->sconn;
579 TALLOC_CTX *mem_ctx = talloc_tos();
580 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
581 uint8_t *inbuf;
583 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
584 msg->buf.length);
585 if (inbuf == NULL) {
586 exit_server("smbd_deferred_open_timer: talloc failed\n");
587 return;
590 /* We leave this message on the queue so the open code can
591 know this is a retry. */
592 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
593 (unsigned long long)mid ));
595 /* Mark the message as processed so this is not
596 * re-processed in error. */
597 msg->processed = true;
599 process_smb(sconn, inbuf,
600 msg->buf.length, 0,
601 msg->seqnum, msg->encrypted, &msg->pcd);
603 /* If it's still there and was processed, remove it. */
604 msg = get_deferred_open_message_smb(sconn, mid);
605 if (msg && msg->processed) {
606 remove_deferred_open_message_smb(sconn, mid);
610 /****************************************************************************
611 Function to push a message onto the tail of a linked list of smb messages ready
612 for processing.
613 ****************************************************************************/
615 static bool push_queued_message(struct smb_request *req,
616 struct timeval request_time,
617 struct timeval end_time,
618 char *private_data, size_t private_len)
620 int msg_len = smb_len(req->inbuf) + 4;
621 struct pending_message_list *msg;
623 msg = talloc_zero(NULL, struct pending_message_list);
625 if(msg == NULL) {
626 DEBUG(0,("push_message: malloc fail (1)\n"));
627 return False;
629 msg->sconn = req->sconn;
631 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
632 if(msg->buf.data == NULL) {
633 DEBUG(0,("push_message: malloc fail (2)\n"));
634 TALLOC_FREE(msg);
635 return False;
638 msg->request_time = request_time;
639 msg->seqnum = req->seqnum;
640 msg->encrypted = req->encrypted;
641 msg->processed = false;
642 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
644 if (private_data) {
645 msg->private_data = data_blob_talloc(msg, private_data,
646 private_len);
647 if (msg->private_data.data == NULL) {
648 DEBUG(0,("push_message: malloc fail (3)\n"));
649 TALLOC_FREE(msg);
650 return False;
654 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
655 msg,
656 end_time,
657 smbd_deferred_open_timer,
658 msg);
659 if (!msg->te) {
660 DEBUG(0,("push_message: event_add_timed failed\n"));
661 TALLOC_FREE(msg);
662 return false;
665 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
666 struct pending_message_list *);
668 DEBUG(10,("push_message: pushed message length %u on "
669 "deferred_open_queue\n", (unsigned int)msg_len));
671 return True;
674 /****************************************************************************
675 Function to delete a sharing violation open message by mid.
676 ****************************************************************************/
678 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
679 uint64_t mid)
681 struct pending_message_list *pml;
683 if (sconn->using_smb2) {
684 remove_deferred_open_message_smb2(sconn, mid);
685 return;
688 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
689 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
690 DEBUG(10,("remove_deferred_open_message_smb: "
691 "deleting mid %llu len %u\n",
692 (unsigned long long)mid,
693 (unsigned int)pml->buf.length ));
694 DLIST_REMOVE(sconn->deferred_open_queue, pml);
695 TALLOC_FREE(pml);
696 return;
701 /****************************************************************************
702 Move a sharing violation open retry message to the front of the list and
703 schedule it for immediate processing.
704 ****************************************************************************/
706 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
707 uint64_t mid)
709 struct pending_message_list *pml;
710 int i = 0;
712 if (sconn->using_smb2) {
713 schedule_deferred_open_message_smb2(sconn, mid);
714 return;
717 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
718 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
720 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
721 "msg_mid = %llu\n",
722 i++,
723 (unsigned long long)msg_mid ));
725 if (mid == msg_mid) {
726 struct timed_event *te;
728 if (pml->processed) {
729 /* A processed message should not be
730 * rescheduled. */
731 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
732 "message mid %llu was already processed\n",
733 (unsigned long long)msg_mid ));
734 continue;
737 DEBUG(10,("schedule_deferred_open_message_smb: "
738 "scheduling mid %llu\n",
739 (unsigned long long)mid ));
741 te = tevent_add_timer(pml->sconn->ev_ctx,
742 pml,
743 timeval_zero(),
744 smbd_deferred_open_timer,
745 pml);
746 if (!te) {
747 DEBUG(10,("schedule_deferred_open_message_smb: "
748 "event_add_timed() failed, "
749 "skipping mid %llu\n",
750 (unsigned long long)msg_mid ));
753 TALLOC_FREE(pml->te);
754 pml->te = te;
755 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
756 return;
760 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
761 "find message mid %llu\n",
762 (unsigned long long)mid ));
765 /****************************************************************************
766 Return true if this mid is on the deferred queue and was not yet processed.
767 ****************************************************************************/
769 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
771 struct pending_message_list *pml;
773 if (sconn->using_smb2) {
774 return open_was_deferred_smb2(sconn, mid);
777 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
778 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
779 return True;
782 return False;
785 /****************************************************************************
786 Return the message queued by this mid.
787 ****************************************************************************/
789 static struct pending_message_list *get_deferred_open_message_smb(
790 struct smbd_server_connection *sconn, uint64_t mid)
792 struct pending_message_list *pml;
794 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
795 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
796 return pml;
799 return NULL;
802 /****************************************************************************
803 Get the state data queued by this mid.
804 ****************************************************************************/
806 bool get_deferred_open_message_state(struct smb_request *smbreq,
807 struct timeval *p_request_time,
808 void **pp_state)
810 struct pending_message_list *pml;
812 if (smbreq->sconn->using_smb2) {
813 return get_deferred_open_message_state_smb2(smbreq->smb2req,
814 p_request_time,
815 pp_state);
818 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
819 if (!pml) {
820 return false;
822 if (p_request_time) {
823 *p_request_time = pml->request_time;
825 if (pp_state) {
826 *pp_state = (void *)pml->private_data.data;
828 return true;
831 /****************************************************************************
832 Function to push a deferred open smb message onto a linked list of local smb
833 messages ready for processing.
834 ****************************************************************************/
836 bool push_deferred_open_message_smb(struct smb_request *req,
837 struct timeval request_time,
838 struct timeval timeout,
839 struct file_id id,
840 char *private_data, size_t priv_len)
842 struct timeval end_time;
844 if (req->smb2req) {
845 return push_deferred_open_message_smb2(req->smb2req,
846 request_time,
847 timeout,
849 private_data,
850 priv_len);
853 if (req->unread_bytes) {
854 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
855 "unread_bytes = %u\n",
856 (unsigned int)req->unread_bytes ));
857 smb_panic("push_deferred_open_message_smb: "
858 "logic error unread_bytes != 0" );
861 end_time = timeval_sum(&request_time, &timeout);
863 DEBUG(10,("push_deferred_open_message_smb: pushing message "
864 "len %u mid %llu timeout time [%u.%06u]\n",
865 (unsigned int) smb_len(req->inbuf)+4,
866 (unsigned long long)req->mid,
867 (unsigned int)end_time.tv_sec,
868 (unsigned int)end_time.tv_usec));
870 return push_queued_message(req, request_time, end_time,
871 private_data, priv_len);
874 static void smbd_sig_term_handler(struct tevent_context *ev,
875 struct tevent_signal *se,
876 int signum,
877 int count,
878 void *siginfo,
879 void *private_data)
881 exit_server_cleanly("termination signal");
884 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
886 struct tevent_signal *se;
888 se = tevent_add_signal(sconn->ev_ctx,
889 sconn,
890 SIGTERM, 0,
891 smbd_sig_term_handler,
892 sconn);
893 if (!se) {
894 exit_server("failed to setup SIGTERM handler");
898 static void smbd_sig_hup_handler(struct tevent_context *ev,
899 struct tevent_signal *se,
900 int signum,
901 int count,
902 void *siginfo,
903 void *private_data)
905 struct smbd_server_connection *sconn =
906 talloc_get_type_abort(private_data,
907 struct smbd_server_connection);
909 change_to_root_user();
910 DEBUG(1,("Reloading services after SIGHUP\n"));
911 reload_services(sconn, conn_snum_used, false);
914 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
916 struct tevent_signal *se;
918 se = tevent_add_signal(sconn->ev_ctx,
919 sconn,
920 SIGHUP, 0,
921 smbd_sig_hup_handler,
922 sconn);
923 if (!se) {
924 exit_server("failed to setup SIGHUP handler");
928 static void smbd_conf_updated(struct messaging_context *msg,
929 void *private_data,
930 uint32_t msg_type,
931 struct server_id server_id,
932 DATA_BLOB *data)
934 struct smbd_server_connection *sconn =
935 talloc_get_type_abort(private_data,
936 struct smbd_server_connection);
938 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
939 "updated. Reloading.\n"));
940 change_to_root_user();
941 reload_services(sconn, conn_snum_used, false);
944 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
945 struct smbd_server_connection *conn)
947 int timeout;
948 int num_pfds = 0;
949 int ret;
950 bool retry;
952 timeout = SMBD_SELECT_TIMEOUT * 1000;
955 * Are there any timed events waiting ? If so, ensure we don't
956 * select for longer than it would take to wait for them.
959 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
961 /* Process a signal and timed events now... */
962 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
963 return NT_STATUS_RETRY;
967 int sav;
968 START_PROFILE(smbd_idle);
970 ret = sys_poll(conn->pfds, num_pfds, timeout);
971 sav = errno;
973 END_PROFILE(smbd_idle);
974 errno = sav;
977 if (ret == -1) {
978 if (errno == EINTR) {
979 return NT_STATUS_RETRY;
981 return map_nt_error_from_unix(errno);
984 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
985 if (retry) {
986 return NT_STATUS_RETRY;
989 /* Did we timeout ? */
990 if (ret == 0) {
991 return NT_STATUS_RETRY;
994 /* should not be reached */
995 return NT_STATUS_INTERNAL_ERROR;
999 * Only allow 5 outstanding trans requests. We're allocating memory, so
1000 * prevent a DoS.
1003 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1005 int count = 0;
1006 for (; list != NULL; list = list->next) {
1008 if (list->mid == mid) {
1009 return NT_STATUS_INVALID_PARAMETER;
1012 count += 1;
1014 if (count > 5) {
1015 return NT_STATUS_INSUFFICIENT_RESOURCES;
1018 return NT_STATUS_OK;
1022 These flags determine some of the permissions required to do an operation
1024 Note that I don't set NEED_WRITE on some write operations because they
1025 are used by some brain-dead clients when printing, and I don't want to
1026 force write permissions on print services.
1028 #define AS_USER (1<<0)
1029 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1030 #define TIME_INIT (1<<2)
1031 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1032 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1033 #define DO_CHDIR (1<<6)
1036 define a list of possible SMB messages and their corresponding
1037 functions. Any message that has a NULL function is unimplemented -
1038 please feel free to contribute implementations!
1040 static const struct smb_message_struct {
1041 const char *name;
1042 void (*fn)(struct smb_request *req);
1043 int flags;
1044 } smb_messages[256] = {
1046 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1047 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1048 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1049 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1050 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1051 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1052 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1053 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1054 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1055 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1056 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1057 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1058 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1059 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1060 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1061 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1062 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1063 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1064 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1065 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1066 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1067 /* 0x15 */ { NULL, NULL, 0 },
1068 /* 0x16 */ { NULL, NULL, 0 },
1069 /* 0x17 */ { NULL, NULL, 0 },
1070 /* 0x18 */ { NULL, NULL, 0 },
1071 /* 0x19 */ { NULL, NULL, 0 },
1072 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1073 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1074 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1075 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1076 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1077 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1078 /* 0x20 */ { "SMBwritec", NULL,0},
1079 /* 0x21 */ { NULL, NULL, 0 },
1080 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1081 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1082 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1083 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1084 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1085 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1086 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1087 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1088 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1089 /* 0x2b */ { "SMBecho",reply_echo,0},
1090 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1091 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1092 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1093 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1094 /* 0x30 */ { NULL, NULL, 0 },
1095 /* 0x31 */ { NULL, NULL, 0 },
1096 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1097 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1098 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1099 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1100 /* 0x36 */ { NULL, NULL, 0 },
1101 /* 0x37 */ { NULL, NULL, 0 },
1102 /* 0x38 */ { NULL, NULL, 0 },
1103 /* 0x39 */ { NULL, NULL, 0 },
1104 /* 0x3a */ { NULL, NULL, 0 },
1105 /* 0x3b */ { NULL, NULL, 0 },
1106 /* 0x3c */ { NULL, NULL, 0 },
1107 /* 0x3d */ { NULL, NULL, 0 },
1108 /* 0x3e */ { NULL, NULL, 0 },
1109 /* 0x3f */ { NULL, NULL, 0 },
1110 /* 0x40 */ { NULL, NULL, 0 },
1111 /* 0x41 */ { NULL, NULL, 0 },
1112 /* 0x42 */ { NULL, NULL, 0 },
1113 /* 0x43 */ { NULL, NULL, 0 },
1114 /* 0x44 */ { NULL, NULL, 0 },
1115 /* 0x45 */ { NULL, NULL, 0 },
1116 /* 0x46 */ { NULL, NULL, 0 },
1117 /* 0x47 */ { NULL, NULL, 0 },
1118 /* 0x48 */ { NULL, NULL, 0 },
1119 /* 0x49 */ { NULL, NULL, 0 },
1120 /* 0x4a */ { NULL, NULL, 0 },
1121 /* 0x4b */ { NULL, NULL, 0 },
1122 /* 0x4c */ { NULL, NULL, 0 },
1123 /* 0x4d */ { NULL, NULL, 0 },
1124 /* 0x4e */ { NULL, NULL, 0 },
1125 /* 0x4f */ { NULL, NULL, 0 },
1126 /* 0x50 */ { NULL, NULL, 0 },
1127 /* 0x51 */ { NULL, NULL, 0 },
1128 /* 0x52 */ { NULL, NULL, 0 },
1129 /* 0x53 */ { NULL, NULL, 0 },
1130 /* 0x54 */ { NULL, NULL, 0 },
1131 /* 0x55 */ { NULL, NULL, 0 },
1132 /* 0x56 */ { NULL, NULL, 0 },
1133 /* 0x57 */ { NULL, NULL, 0 },
1134 /* 0x58 */ { NULL, NULL, 0 },
1135 /* 0x59 */ { NULL, NULL, 0 },
1136 /* 0x5a */ { NULL, NULL, 0 },
1137 /* 0x5b */ { NULL, NULL, 0 },
1138 /* 0x5c */ { NULL, NULL, 0 },
1139 /* 0x5d */ { NULL, NULL, 0 },
1140 /* 0x5e */ { NULL, NULL, 0 },
1141 /* 0x5f */ { NULL, NULL, 0 },
1142 /* 0x60 */ { NULL, NULL, 0 },
1143 /* 0x61 */ { NULL, NULL, 0 },
1144 /* 0x62 */ { NULL, NULL, 0 },
1145 /* 0x63 */ { NULL, NULL, 0 },
1146 /* 0x64 */ { NULL, NULL, 0 },
1147 /* 0x65 */ { NULL, NULL, 0 },
1148 /* 0x66 */ { NULL, NULL, 0 },
1149 /* 0x67 */ { NULL, NULL, 0 },
1150 /* 0x68 */ { NULL, NULL, 0 },
1151 /* 0x69 */ { NULL, NULL, 0 },
1152 /* 0x6a */ { NULL, NULL, 0 },
1153 /* 0x6b */ { NULL, NULL, 0 },
1154 /* 0x6c */ { NULL, NULL, 0 },
1155 /* 0x6d */ { NULL, NULL, 0 },
1156 /* 0x6e */ { NULL, NULL, 0 },
1157 /* 0x6f */ { NULL, NULL, 0 },
1158 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1159 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1160 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1161 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1162 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1163 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1164 /* 0x76 */ { NULL, NULL, 0 },
1165 /* 0x77 */ { NULL, NULL, 0 },
1166 /* 0x78 */ { NULL, NULL, 0 },
1167 /* 0x79 */ { NULL, NULL, 0 },
1168 /* 0x7a */ { NULL, NULL, 0 },
1169 /* 0x7b */ { NULL, NULL, 0 },
1170 /* 0x7c */ { NULL, NULL, 0 },
1171 /* 0x7d */ { NULL, NULL, 0 },
1172 /* 0x7e */ { NULL, NULL, 0 },
1173 /* 0x7f */ { NULL, NULL, 0 },
1174 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1175 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1176 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1177 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1178 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1179 /* 0x85 */ { NULL, NULL, 0 },
1180 /* 0x86 */ { NULL, NULL, 0 },
1181 /* 0x87 */ { NULL, NULL, 0 },
1182 /* 0x88 */ { NULL, NULL, 0 },
1183 /* 0x89 */ { NULL, NULL, 0 },
1184 /* 0x8a */ { NULL, NULL, 0 },
1185 /* 0x8b */ { NULL, NULL, 0 },
1186 /* 0x8c */ { NULL, NULL, 0 },
1187 /* 0x8d */ { NULL, NULL, 0 },
1188 /* 0x8e */ { NULL, NULL, 0 },
1189 /* 0x8f */ { NULL, NULL, 0 },
1190 /* 0x90 */ { NULL, NULL, 0 },
1191 /* 0x91 */ { NULL, NULL, 0 },
1192 /* 0x92 */ { NULL, NULL, 0 },
1193 /* 0x93 */ { NULL, NULL, 0 },
1194 /* 0x94 */ { NULL, NULL, 0 },
1195 /* 0x95 */ { NULL, NULL, 0 },
1196 /* 0x96 */ { NULL, NULL, 0 },
1197 /* 0x97 */ { NULL, NULL, 0 },
1198 /* 0x98 */ { NULL, NULL, 0 },
1199 /* 0x99 */ { NULL, NULL, 0 },
1200 /* 0x9a */ { NULL, NULL, 0 },
1201 /* 0x9b */ { NULL, NULL, 0 },
1202 /* 0x9c */ { NULL, NULL, 0 },
1203 /* 0x9d */ { NULL, NULL, 0 },
1204 /* 0x9e */ { NULL, NULL, 0 },
1205 /* 0x9f */ { NULL, NULL, 0 },
1206 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1207 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1208 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1209 /* 0xa3 */ { NULL, NULL, 0 },
1210 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1211 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1212 /* 0xa6 */ { NULL, NULL, 0 },
1213 /* 0xa7 */ { NULL, NULL, 0 },
1214 /* 0xa8 */ { NULL, NULL, 0 },
1215 /* 0xa9 */ { NULL, NULL, 0 },
1216 /* 0xaa */ { NULL, NULL, 0 },
1217 /* 0xab */ { NULL, NULL, 0 },
1218 /* 0xac */ { NULL, NULL, 0 },
1219 /* 0xad */ { NULL, NULL, 0 },
1220 /* 0xae */ { NULL, NULL, 0 },
1221 /* 0xaf */ { NULL, NULL, 0 },
1222 /* 0xb0 */ { NULL, NULL, 0 },
1223 /* 0xb1 */ { NULL, NULL, 0 },
1224 /* 0xb2 */ { NULL, NULL, 0 },
1225 /* 0xb3 */ { NULL, NULL, 0 },
1226 /* 0xb4 */ { NULL, NULL, 0 },
1227 /* 0xb5 */ { NULL, NULL, 0 },
1228 /* 0xb6 */ { NULL, NULL, 0 },
1229 /* 0xb7 */ { NULL, NULL, 0 },
1230 /* 0xb8 */ { NULL, NULL, 0 },
1231 /* 0xb9 */ { NULL, NULL, 0 },
1232 /* 0xba */ { NULL, NULL, 0 },
1233 /* 0xbb */ { NULL, NULL, 0 },
1234 /* 0xbc */ { NULL, NULL, 0 },
1235 /* 0xbd */ { NULL, NULL, 0 },
1236 /* 0xbe */ { NULL, NULL, 0 },
1237 /* 0xbf */ { NULL, NULL, 0 },
1238 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1239 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1240 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1241 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1242 /* 0xc4 */ { NULL, NULL, 0 },
1243 /* 0xc5 */ { NULL, NULL, 0 },
1244 /* 0xc6 */ { NULL, NULL, 0 },
1245 /* 0xc7 */ { NULL, NULL, 0 },
1246 /* 0xc8 */ { NULL, NULL, 0 },
1247 /* 0xc9 */ { NULL, NULL, 0 },
1248 /* 0xca */ { NULL, NULL, 0 },
1249 /* 0xcb */ { NULL, NULL, 0 },
1250 /* 0xcc */ { NULL, NULL, 0 },
1251 /* 0xcd */ { NULL, NULL, 0 },
1252 /* 0xce */ { NULL, NULL, 0 },
1253 /* 0xcf */ { NULL, NULL, 0 },
1254 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1255 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1256 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1257 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1258 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1259 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1260 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1261 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1262 /* 0xd8 */ { NULL, NULL, 0 },
1263 /* 0xd9 */ { NULL, NULL, 0 },
1264 /* 0xda */ { NULL, NULL, 0 },
1265 /* 0xdb */ { NULL, NULL, 0 },
1266 /* 0xdc */ { NULL, NULL, 0 },
1267 /* 0xdd */ { NULL, NULL, 0 },
1268 /* 0xde */ { NULL, NULL, 0 },
1269 /* 0xdf */ { NULL, NULL, 0 },
1270 /* 0xe0 */ { NULL, NULL, 0 },
1271 /* 0xe1 */ { NULL, NULL, 0 },
1272 /* 0xe2 */ { NULL, NULL, 0 },
1273 /* 0xe3 */ { NULL, NULL, 0 },
1274 /* 0xe4 */ { NULL, NULL, 0 },
1275 /* 0xe5 */ { NULL, NULL, 0 },
1276 /* 0xe6 */ { NULL, NULL, 0 },
1277 /* 0xe7 */ { NULL, NULL, 0 },
1278 /* 0xe8 */ { NULL, NULL, 0 },
1279 /* 0xe9 */ { NULL, NULL, 0 },
1280 /* 0xea */ { NULL, NULL, 0 },
1281 /* 0xeb */ { NULL, NULL, 0 },
1282 /* 0xec */ { NULL, NULL, 0 },
1283 /* 0xed */ { NULL, NULL, 0 },
1284 /* 0xee */ { NULL, NULL, 0 },
1285 /* 0xef */ { NULL, NULL, 0 },
1286 /* 0xf0 */ { NULL, NULL, 0 },
1287 /* 0xf1 */ { NULL, NULL, 0 },
1288 /* 0xf2 */ { NULL, NULL, 0 },
1289 /* 0xf3 */ { NULL, NULL, 0 },
1290 /* 0xf4 */ { NULL, NULL, 0 },
1291 /* 0xf5 */ { NULL, NULL, 0 },
1292 /* 0xf6 */ { NULL, NULL, 0 },
1293 /* 0xf7 */ { NULL, NULL, 0 },
1294 /* 0xf8 */ { NULL, NULL, 0 },
1295 /* 0xf9 */ { NULL, NULL, 0 },
1296 /* 0xfa */ { NULL, NULL, 0 },
1297 /* 0xfb */ { NULL, NULL, 0 },
1298 /* 0xfc */ { NULL, NULL, 0 },
1299 /* 0xfd */ { NULL, NULL, 0 },
1300 /* 0xfe */ { NULL, NULL, 0 },
1301 /* 0xff */ { NULL, NULL, 0 }
1305 /*******************************************************************
1306 allocate and initialize a reply packet
1307 ********************************************************************/
1309 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1310 const char *inbuf, char **outbuf, uint8_t num_words,
1311 uint32_t num_bytes)
1314 * Protect against integer wrap
1316 if ((num_bytes > 0xffffff)
1317 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1318 char *msg;
1319 if (asprintf(&msg, "num_bytes too large: %u",
1320 (unsigned)num_bytes) == -1) {
1321 msg = discard_const_p(char, "num_bytes too large");
1323 smb_panic(msg);
1326 *outbuf = talloc_array(mem_ctx, char,
1327 smb_size + num_words*2 + num_bytes);
1328 if (*outbuf == NULL) {
1329 return false;
1332 construct_reply_common(req, inbuf, *outbuf);
1333 srv_set_message(*outbuf, num_words, num_bytes, false);
1335 * Zero out the word area, the caller has to take care of the bcc area
1336 * himself
1338 if (num_words != 0) {
1339 memset(*outbuf + smb_vwv0, 0, num_words*2);
1342 return true;
1345 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1347 char *outbuf;
1348 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1349 num_bytes)) {
1350 smb_panic("could not allocate output buffer\n");
1352 req->outbuf = (uint8_t *)outbuf;
1356 /*******************************************************************
1357 Dump a packet to a file.
1358 ********************************************************************/
1360 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1362 int fd, i;
1363 char *fname = NULL;
1364 if (DEBUGLEVEL < 50) {
1365 return;
1368 if (len < 4) len = smb_len(data)+4;
1369 for (i=1;i<100;i++) {
1370 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1371 type ? "req" : "resp") == -1) {
1372 return;
1374 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1375 if (fd != -1 || errno != EEXIST) break;
1377 if (fd != -1) {
1378 ssize_t ret = write(fd, data, len);
1379 if (ret != len)
1380 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1381 close(fd);
1382 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1384 SAFE_FREE(fname);
1387 /****************************************************************************
1388 Prepare everything for calling the actual request function, and potentially
1389 call the request function via the "new" interface.
1391 Return False if the "legacy" function needs to be called, everything is
1392 prepared.
1394 Return True if we're done.
1396 I know this API sucks, but it is the one with the least code change I could
1397 find.
1398 ****************************************************************************/
1400 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1402 int flags;
1403 uint16 session_tag;
1404 connection_struct *conn = NULL;
1405 struct smbd_server_connection *sconn = req->sconn;
1406 char *raddr;
1408 errno = 0;
1410 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1411 * so subtract 4 from it. */
1412 if (!valid_smb_header(sconn, req->inbuf)
1413 || (size < (smb_size - 4))) {
1414 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1415 smb_len(req->inbuf)));
1416 exit_server_cleanly("Non-SMB packet");
1419 if (smb_messages[type].fn == NULL) {
1420 DEBUG(0,("Unknown message type %d!\n",type));
1421 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1422 reply_unknown_new(req, type);
1423 return NULL;
1426 flags = smb_messages[type].flags;
1428 /* In share mode security we must ignore the vuid. */
1429 session_tag = (lp_security() == SEC_SHARE)
1430 ? UID_FIELD_INVALID : req->vuid;
1431 conn = req->conn;
1433 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1434 (int)sys_getpid(), (unsigned long)conn));
1436 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1438 /* Ensure this value is replaced in the incoming packet. */
1439 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1442 * Ensure the correct username is in current_user_info. This is a
1443 * really ugly bugfix for problems with multiple session_setup_and_X's
1444 * being done and allowing %U and %G substitutions to work correctly.
1445 * There is a reason this code is done here, don't move it unless you
1446 * know what you're doing... :-).
1447 * JRA.
1450 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1451 user_struct *vuser = NULL;
1453 sconn->smb1.sessions.last_session_tag = session_tag;
1454 if(session_tag != UID_FIELD_INVALID) {
1455 vuser = get_valid_user_struct(sconn, session_tag);
1456 if (vuser) {
1457 set_current_user_info(
1458 vuser->session_info->unix_info->sanitized_username,
1459 vuser->session_info->unix_info->unix_name,
1460 vuser->session_info->info->domain_name);
1465 /* Does this call need to be run as the connected user? */
1466 if (flags & AS_USER) {
1468 /* Does this call need a valid tree connection? */
1469 if (!conn) {
1471 * Amazingly, the error code depends on the command
1472 * (from Samba4).
1474 if (type == SMBntcreateX) {
1475 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1476 } else {
1477 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1479 return NULL;
1482 if (!change_to_user(conn,session_tag)) {
1483 DEBUG(0, ("Error: Could not change to user. Removing "
1484 "deferred open, mid=%llu.\n",
1485 (unsigned long long)req->mid));
1486 reply_force_doserror(req, ERRSRV, ERRbaduid);
1487 return conn;
1490 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1492 /* Does it need write permission? */
1493 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1494 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1495 return conn;
1498 /* IPC services are limited */
1499 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1500 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1501 return conn;
1503 } else {
1504 /* This call needs to be run as root */
1505 change_to_root_user();
1508 /* load service specific parameters */
1509 if (conn) {
1510 if (req->encrypted) {
1511 conn->encrypted_tid = true;
1512 /* encrypted required from now on. */
1513 conn->encrypt_level = Required;
1514 } else if (ENCRYPTION_REQUIRED(conn)) {
1515 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1516 exit_server_cleanly("encryption required "
1517 "on connection");
1518 return conn;
1522 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1523 (flags & (AS_USER|DO_CHDIR)
1524 ?True:False))) {
1525 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1526 return conn;
1528 conn->num_smb_operations++;
1531 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1532 talloc_tos());
1533 if (raddr == NULL) {
1534 reply_nterror(req, NT_STATUS_NO_MEMORY);
1535 return conn;
1538 /* does this protocol need to be run as guest? */
1539 if ((flags & AS_GUEST)
1540 && (!change_to_guest() ||
1541 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1542 sconn->remote_hostname,
1543 raddr))) {
1544 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1545 return conn;
1548 smb_messages[type].fn(req);
1549 return req->conn;
1552 /****************************************************************************
1553 Construct a reply to the incoming packet.
1554 ****************************************************************************/
1556 static void construct_reply(struct smbd_server_connection *sconn,
1557 char *inbuf, int size, size_t unread_bytes,
1558 uint32_t seqnum, bool encrypted,
1559 struct smb_perfcount_data *deferred_pcd)
1561 connection_struct *conn;
1562 struct smb_request *req;
1564 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1565 smb_panic("could not allocate smb_request");
1568 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1569 encrypted, seqnum)) {
1570 exit_server_cleanly("Invalid SMB request");
1573 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1575 /* we popped this message off the queue - keep original perf data */
1576 if (deferred_pcd)
1577 req->pcd = *deferred_pcd;
1578 else {
1579 SMB_PERFCOUNT_START(&req->pcd);
1580 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1581 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1584 conn = switch_message(req->cmd, req, size);
1586 if (req->unread_bytes) {
1587 /* writeX failed. drain socket. */
1588 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1589 req->unread_bytes) {
1590 smb_panic("failed to drain pending bytes");
1592 req->unread_bytes = 0;
1595 if (req->done) {
1596 TALLOC_FREE(req);
1597 return;
1600 if (req->outbuf == NULL) {
1601 return;
1604 if (CVAL(req->outbuf,0) == 0) {
1605 show_msg((char *)req->outbuf);
1608 if (!srv_send_smb(req->sconn,
1609 (char *)req->outbuf,
1610 true, req->seqnum+1,
1611 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1612 &req->pcd)) {
1613 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1616 TALLOC_FREE(req);
1618 return;
1621 /****************************************************************************
1622 Process an smb from the client
1623 ****************************************************************************/
1624 static void process_smb(struct smbd_server_connection *sconn,
1625 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1626 uint32_t seqnum, bool encrypted,
1627 struct smb_perfcount_data *deferred_pcd)
1629 int msg_type = CVAL(inbuf,0);
1631 DO_PROFILE_INC(smb_count);
1633 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1634 smb_len(inbuf) ) );
1635 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1636 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1638 if (msg_type != NBSSmessage) {
1640 * NetBIOS session request, keepalive, etc.
1642 reply_special(sconn, (char *)inbuf, nread);
1643 goto done;
1646 if (sconn->using_smb2) {
1647 /* At this point we're not really using smb2,
1648 * we make the decision here.. */
1649 if (smbd_is_smb2_header(inbuf, nread)) {
1650 smbd_smb2_first_negprot(sconn, inbuf, nread);
1651 return;
1652 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1653 && CVAL(inbuf, smb_com) != 0x72) {
1654 /* This is a non-negprot SMB1 packet.
1655 Disable SMB2 from now on. */
1656 sconn->using_smb2 = false;
1660 show_msg((char *)inbuf);
1662 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1663 encrypted, deferred_pcd);
1664 sconn->trans_num++;
1666 done:
1667 sconn->num_requests++;
1669 /* The timeout_processing function isn't run nearly
1670 often enough to implement 'max log size' without
1671 overrunning the size of the file by many megabytes.
1672 This is especially true if we are running at debug
1673 level 10. Checking every 50 SMBs is a nice
1674 tradeoff of performance vs log file size overrun. */
1676 if ((sconn->num_requests % 50) == 0 &&
1677 need_to_check_log_size()) {
1678 change_to_root_user();
1679 check_log_size();
1683 /****************************************************************************
1684 Return a string containing the function name of a SMB command.
1685 ****************************************************************************/
1687 const char *smb_fn_name(int type)
1689 const char *unknown_name = "SMBunknown";
1691 if (smb_messages[type].name == NULL)
1692 return(unknown_name);
1694 return(smb_messages[type].name);
1697 /****************************************************************************
1698 Helper functions for contruct_reply.
1699 ****************************************************************************/
1701 void add_to_common_flags2(uint32 v)
1703 common_flags2 |= v;
1706 void remove_from_common_flags2(uint32 v)
1708 common_flags2 &= ~v;
1711 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1712 char *outbuf)
1714 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1715 uint16_t out_flags2 = common_flags2;
1717 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1718 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1719 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1721 srv_set_message(outbuf,0,0,false);
1723 SCVAL(outbuf, smb_com, req->cmd);
1724 SIVAL(outbuf,smb_rcls,0);
1725 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1726 SSVAL(outbuf,smb_flg2, out_flags2);
1727 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1728 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1730 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1731 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1732 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1733 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1736 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1738 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1742 * How many bytes have we already accumulated up to the current wct field
1743 * offset?
1746 size_t req_wct_ofs(struct smb_request *req)
1748 size_t buf_size;
1750 if (req->chain_outbuf == NULL) {
1751 return smb_wct - 4;
1753 buf_size = talloc_get_size(req->chain_outbuf);
1754 if ((buf_size % 4) != 0) {
1755 buf_size += (4 - (buf_size % 4));
1757 return buf_size - 4;
1761 * Hack around reply_nterror & friends not being aware of chained requests,
1762 * generating illegal (i.e. wct==0) chain replies.
1765 static void fixup_chain_error_packet(struct smb_request *req)
1767 uint8_t *outbuf = req->outbuf;
1768 req->outbuf = NULL;
1769 reply_outbuf(req, 2, 0);
1770 memcpy(req->outbuf, outbuf, smb_wct);
1771 TALLOC_FREE(outbuf);
1772 SCVAL(req->outbuf, smb_vwv0, 0xff);
1776 * @brief Find the smb_cmd offset of the last command pushed
1777 * @param[in] buf The buffer we're building up
1778 * @retval Where can we put our next andx cmd?
1780 * While chaining requests, the "next" request we're looking at needs to put
1781 * its SMB_Command before the data the previous request already built up added
1782 * to the chain. Find the offset to the place where we have to put our cmd.
1785 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1787 uint8_t cmd;
1788 size_t ofs;
1790 cmd = CVAL(buf, smb_com);
1792 SMB_ASSERT(is_andx_req(cmd));
1794 ofs = smb_vwv0;
1796 while (CVAL(buf, ofs) != 0xff) {
1798 if (!is_andx_req(CVAL(buf, ofs))) {
1799 return false;
1803 * ofs is from start of smb header, so add the 4 length
1804 * bytes. The next cmd is right after the wct field.
1806 ofs = SVAL(buf, ofs+2) + 4 + 1;
1808 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1811 *pofs = ofs;
1812 return true;
1816 * @brief Do the smb chaining at a buffer level
1817 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1818 * @param[in] smb_command The command that we want to issue
1819 * @param[in] wct How many words?
1820 * @param[in] vwv The words, already in network order
1821 * @param[in] bytes_alignment How shall we align "bytes"?
1822 * @param[in] num_bytes How many bytes?
1823 * @param[in] bytes The data the request ships
1825 * smb_splice_chain() adds the vwv and bytes to the request already present in
1826 * *poutbuf.
1829 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1830 uint8_t wct, const uint16_t *vwv,
1831 size_t bytes_alignment,
1832 uint32_t num_bytes, const uint8_t *bytes)
1834 uint8_t *outbuf;
1835 size_t old_size, new_size;
1836 size_t ofs;
1837 size_t chain_padding = 0;
1838 size_t bytes_padding = 0;
1839 bool first_request;
1841 old_size = talloc_get_size(*poutbuf);
1844 * old_size == smb_wct means we're pushing the first request in for
1845 * libsmb/
1848 first_request = (old_size == smb_wct);
1850 if (!first_request && ((old_size % 4) != 0)) {
1852 * Align the wct field of subsequent requests to a 4-byte
1853 * boundary
1855 chain_padding = 4 - (old_size % 4);
1859 * After the old request comes the new wct field (1 byte), the vwv's
1860 * and the num_bytes field. After at we might need to align the bytes
1861 * given to us to "bytes_alignment", increasing the num_bytes value.
1864 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1866 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1867 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1870 new_size += bytes_padding + num_bytes;
1872 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1873 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1874 (unsigned)new_size));
1875 return false;
1878 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1879 if (outbuf == NULL) {
1880 DEBUG(0, ("talloc failed\n"));
1881 return false;
1883 *poutbuf = outbuf;
1885 if (first_request) {
1886 SCVAL(outbuf, smb_com, smb_command);
1887 } else {
1888 size_t andx_cmd_ofs;
1890 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1891 DEBUG(1, ("invalid command chain\n"));
1892 *poutbuf = talloc_realloc(
1893 NULL, *poutbuf, uint8_t, old_size);
1894 return false;
1897 if (chain_padding != 0) {
1898 memset(outbuf + old_size, 0, chain_padding);
1899 old_size += chain_padding;
1902 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1903 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1906 ofs = old_size;
1909 * Push the chained request:
1911 * wct field
1914 SCVAL(outbuf, ofs, wct);
1915 ofs += 1;
1918 * vwv array
1921 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1922 ofs += sizeof(uint16_t) * wct;
1925 * bcc (byte count)
1928 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1929 ofs += sizeof(uint16_t);
1932 * padding
1935 if (bytes_padding != 0) {
1936 memset(outbuf + ofs, 0, bytes_padding);
1937 ofs += bytes_padding;
1941 * The bytes field
1944 memcpy(outbuf + ofs, bytes, num_bytes);
1946 return true;
1949 /****************************************************************************
1950 Construct a chained reply and add it to the already made reply
1951 ****************************************************************************/
1953 void chain_reply(struct smb_request *req)
1955 size_t smblen = smb_len(req->inbuf);
1956 size_t already_used, length_needed;
1957 uint8_t chain_cmd;
1958 uint32_t chain_offset; /* uint32_t to avoid overflow */
1960 uint8_t wct;
1961 const uint16_t *vwv;
1962 uint16_t buflen;
1963 const uint8_t *buf;
1965 if (IVAL(req->outbuf, smb_rcls) != 0) {
1966 fixup_chain_error_packet(req);
1970 * Any of the AndX requests and replies have at least a wct of
1971 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1972 * beginning of the SMB header to the next wct field.
1974 * None of the AndX requests put anything valuable in vwv[0] and [1],
1975 * so we can overwrite it here to form the chain.
1978 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1979 if (req->chain_outbuf == NULL) {
1980 req->chain_outbuf = talloc_realloc(
1981 req, req->outbuf, uint8_t,
1982 smb_len(req->outbuf) + 4);
1983 if (req->chain_outbuf == NULL) {
1984 smb_panic("talloc failed");
1987 req->outbuf = NULL;
1988 goto error;
1992 * Here we assume that this is the end of the chain. For that we need
1993 * to set "next command" to 0xff and the offset to 0. If we later find
1994 * more commands in the chain, this will be overwritten again.
1997 SCVAL(req->outbuf, smb_vwv0, 0xff);
1998 SCVAL(req->outbuf, smb_vwv0+1, 0);
1999 SSVAL(req->outbuf, smb_vwv1, 0);
2001 if (req->chain_outbuf == NULL) {
2003 * In req->chain_outbuf we collect all the replies. Start the
2004 * chain by copying in the first reply.
2006 * We do the realloc because later on we depend on
2007 * talloc_get_size to determine the length of
2008 * chain_outbuf. The reply_xxx routines might have
2009 * over-allocated (reply_pipe_read_and_X used to be such an
2010 * example).
2012 req->chain_outbuf = talloc_realloc(
2013 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2014 if (req->chain_outbuf == NULL) {
2015 smb_panic("talloc failed");
2017 req->outbuf = NULL;
2018 } else {
2020 * Update smb headers where subsequent chained commands
2021 * may have updated them.
2023 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2024 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2026 if (!smb_splice_chain(&req->chain_outbuf,
2027 CVAL(req->outbuf, smb_com),
2028 CVAL(req->outbuf, smb_wct),
2029 (uint16_t *)(req->outbuf + smb_vwv),
2030 0, smb_buflen(req->outbuf),
2031 (uint8_t *)smb_buf(req->outbuf))) {
2032 goto error;
2034 TALLOC_FREE(req->outbuf);
2038 * We use the old request's vwv field to grab the next chained command
2039 * and offset into the chained fields.
2042 chain_cmd = CVAL(req->vwv+0, 0);
2043 chain_offset = SVAL(req->vwv+1, 0);
2045 if (chain_cmd == 0xff) {
2047 * End of chain, no more requests from the client. So ship the
2048 * replies.
2050 smb_setlen((char *)(req->chain_outbuf),
2051 talloc_get_size(req->chain_outbuf) - 4);
2053 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2054 true, req->seqnum+1,
2055 IS_CONN_ENCRYPTED(req->conn)
2056 ||req->encrypted,
2057 &req->pcd)) {
2058 exit_server_cleanly("chain_reply: srv_send_smb "
2059 "failed.");
2061 TALLOC_FREE(req->chain_outbuf);
2062 req->done = true;
2063 return;
2066 /* add a new perfcounter for this element of chain */
2067 SMB_PERFCOUNT_ADD(&req->pcd);
2068 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2069 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2072 * Check if the client tries to fool us. The chain offset
2073 * needs to point beyond the current request in the chain, it
2074 * needs to strictly grow. Otherwise we might be tricked into
2075 * an endless loop always processing the same request over and
2076 * over again. We used to assume that vwv and the byte buffer
2077 * array in a chain are always attached, but OS/2 the
2078 * Write&X/Read&X chain puts the Read&X vwv array right behind
2079 * the Write&X vwv chain. The Write&X bcc array is put behind
2080 * the Read&X vwv array. So now we check whether the chain
2081 * offset points strictly behind the previous vwv
2082 * array. req->buf points right after the vwv array of the
2083 * previous request. See
2084 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2085 * information.
2088 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2089 if (chain_offset <= already_used) {
2090 goto error;
2094 * Next check: Make sure the chain offset does not point beyond the
2095 * overall smb request length.
2098 length_needed = chain_offset+1; /* wct */
2099 if (length_needed > smblen) {
2100 goto error;
2104 * Now comes the pointer magic. Goal here is to set up req->vwv and
2105 * req->buf correctly again to be able to call the subsequent
2106 * switch_message(). The chain offset (the former vwv[1]) points at
2107 * the new wct field.
2110 wct = CVAL(smb_base(req->inbuf), chain_offset);
2113 * Next consistency check: Make the new vwv array fits in the overall
2114 * smb request.
2117 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2118 if (length_needed > smblen) {
2119 goto error;
2121 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2124 * Now grab the new byte buffer....
2127 buflen = SVAL(vwv+wct, 0);
2130 * .. and check that it fits.
2133 length_needed += buflen;
2134 if (length_needed > smblen) {
2135 goto error;
2137 buf = (const uint8_t *)(vwv+wct+1);
2139 req->cmd = chain_cmd;
2140 req->wct = wct;
2141 req->vwv = discard_const_p(uint16_t, vwv);
2142 req->buflen = buflen;
2143 req->buf = buf;
2145 switch_message(chain_cmd, req, smblen);
2147 if (req->outbuf == NULL) {
2149 * This happens if the chained command has suspended itself or
2150 * if it has called srv_send_smb() itself.
2152 return;
2156 * We end up here if the chained command was not itself chained or
2157 * suspended, but for example a close() command. We now need to splice
2158 * the chained commands' outbuf into the already built up chain_outbuf
2159 * and ship the result.
2161 goto done;
2163 error:
2165 * We end up here if there's any error in the chain syntax. Report a
2166 * DOS error, just like Windows does.
2168 reply_force_doserror(req, ERRSRV, ERRerror);
2169 fixup_chain_error_packet(req);
2171 done:
2173 * This scary statement intends to set the
2174 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2175 * to the value req->outbuf carries
2177 SSVAL(req->chain_outbuf, smb_flg2,
2178 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2179 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2182 * Transfer the error codes from the subrequest to the main one
2184 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2185 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2187 if (!smb_splice_chain(&req->chain_outbuf,
2188 CVAL(req->outbuf, smb_com),
2189 CVAL(req->outbuf, smb_wct),
2190 (uint16_t *)(req->outbuf + smb_vwv),
2191 0, smb_buflen(req->outbuf),
2192 (uint8_t *)smb_buf(req->outbuf))) {
2193 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2195 TALLOC_FREE(req->outbuf);
2197 smb_setlen((char *)(req->chain_outbuf),
2198 talloc_get_size(req->chain_outbuf) - 4);
2200 show_msg((char *)(req->chain_outbuf));
2202 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2203 true, req->seqnum+1,
2204 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2205 &req->pcd)) {
2206 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2208 TALLOC_FREE(req->chain_outbuf);
2209 req->done = true;
2212 /****************************************************************************
2213 Check if services need reloading.
2214 ****************************************************************************/
2216 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2219 if (last_smb_conf_reload_time == 0) {
2220 last_smb_conf_reload_time = t;
2223 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2224 reload_services(sconn, conn_snum_used, true);
2225 last_smb_conf_reload_time = t;
2229 static bool fd_is_readable(int fd)
2231 int ret, revents;
2233 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2235 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2239 static void smbd_server_connection_write_handler(
2240 struct smbd_server_connection *sconn)
2242 /* TODO: make write nonblocking */
2245 static void smbd_server_connection_read_handler(
2246 struct smbd_server_connection *sconn, int fd)
2248 uint8_t *inbuf = NULL;
2249 size_t inbuf_len = 0;
2250 size_t unread_bytes = 0;
2251 bool encrypted = false;
2252 TALLOC_CTX *mem_ctx = talloc_tos();
2253 NTSTATUS status;
2254 uint32_t seqnum;
2256 bool from_client;
2258 if (lp_async_smb_echo_handler()
2259 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2261 * This is the super-ugly hack to prefer the packets
2262 * forwarded by the echo handler over the ones by the
2263 * client directly
2265 fd = sconn->smb1.echo_handler.trusted_fd;
2268 from_client = (sconn->sock == fd);
2270 if (from_client) {
2271 smbd_lock_socket(sconn);
2273 if (!fd_is_readable(fd)) {
2274 DEBUG(10,("the echo listener was faster\n"));
2275 smbd_unlock_socket(sconn);
2276 return;
2280 /* TODO: make this completely nonblocking */
2281 status = receive_smb_talloc(mem_ctx, sconn, fd,
2282 (char **)(void *)&inbuf,
2283 0, /* timeout */
2284 &unread_bytes,
2285 &encrypted,
2286 &inbuf_len, &seqnum,
2287 false /* trusted channel */);
2289 if (from_client) {
2290 smbd_unlock_socket(sconn);
2293 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2294 goto process;
2296 if (NT_STATUS_IS_ERR(status)) {
2297 exit_server_cleanly("failed to receive smb request");
2299 if (!NT_STATUS_IS_OK(status)) {
2300 return;
2303 process:
2304 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2305 seqnum, encrypted, NULL);
2308 static void smbd_server_connection_handler(struct event_context *ev,
2309 struct fd_event *fde,
2310 uint16_t flags,
2311 void *private_data)
2313 struct smbd_server_connection *conn = talloc_get_type(private_data,
2314 struct smbd_server_connection);
2316 if (flags & EVENT_FD_WRITE) {
2317 smbd_server_connection_write_handler(conn);
2318 return;
2320 if (flags & EVENT_FD_READ) {
2321 smbd_server_connection_read_handler(conn, conn->sock);
2322 return;
2326 static void smbd_server_echo_handler(struct event_context *ev,
2327 struct fd_event *fde,
2328 uint16_t flags,
2329 void *private_data)
2331 struct smbd_server_connection *conn = talloc_get_type(private_data,
2332 struct smbd_server_connection);
2334 if (flags & EVENT_FD_WRITE) {
2335 smbd_server_connection_write_handler(conn);
2336 return;
2338 if (flags & EVENT_FD_READ) {
2339 smbd_server_connection_read_handler(
2340 conn, conn->smb1.echo_handler.trusted_fd);
2341 return;
2345 #ifdef CLUSTER_SUPPORT
2346 /****************************************************************************
2347 received when we should release a specific IP
2348 ****************************************************************************/
2349 static void release_ip(const char *ip, void *priv)
2351 const char *addr = (const char *)priv;
2352 const char *p = addr;
2354 if (strncmp("::ffff:", addr, 7) == 0) {
2355 p = addr + 7;
2358 DEBUG(10, ("Got release IP message for %s, "
2359 "our address is %s\n", ip, p));
2361 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2362 /* we can't afford to do a clean exit - that involves
2363 database writes, which would potentially mean we
2364 are still running after the failover has finished -
2365 we have to get rid of this process ID straight
2366 away */
2367 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2368 ip));
2369 /* note we must exit with non-zero status so the unclean handler gets
2370 called in the parent, so that the brl database is tickled */
2371 _exit(1);
2375 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2376 struct sockaddr_storage *client)
2378 socklen_t length;
2379 length = sizeof(*server);
2380 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2381 return -1;
2383 length = sizeof(*client);
2384 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2385 return -1;
2387 return 0;
2389 #endif
2392 * Send keepalive packets to our client
2394 static bool keepalive_fn(const struct timeval *now, void *private_data)
2396 struct smbd_server_connection *sconn = talloc_get_type_abort(
2397 private_data, struct smbd_server_connection);
2398 bool ret;
2400 if (sconn->using_smb2) {
2401 /* Don't do keepalives on an SMB2 connection. */
2402 return false;
2405 smbd_lock_socket(sconn);
2406 ret = send_keepalive(sconn->sock);
2407 smbd_unlock_socket(sconn);
2409 if (!ret) {
2410 char addr[INET6_ADDRSTRLEN];
2412 * Try and give an error message saying what
2413 * client failed.
2415 DEBUG(0, ("send_keepalive failed for client %s. "
2416 "Error %s - exiting\n",
2417 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2418 strerror(errno)));
2419 return False;
2421 return True;
2425 * Do the recurring check if we're idle
2427 static bool deadtime_fn(const struct timeval *now, void *private_data)
2429 struct smbd_server_connection *sconn =
2430 (struct smbd_server_connection *)private_data;
2432 if ((conn_num_open(sconn) == 0)
2433 || (conn_idle_all(sconn, now->tv_sec))) {
2434 DEBUG( 2, ( "Closing idle connection\n" ) );
2435 messaging_send(sconn->msg_ctx,
2436 messaging_server_id(sconn->msg_ctx),
2437 MSG_SHUTDOWN, &data_blob_null);
2438 return False;
2441 return True;
2445 * Do the recurring log file and smb.conf reload checks.
2448 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2450 struct smbd_server_connection *sconn = talloc_get_type_abort(
2451 private_data, struct smbd_server_connection);
2453 DEBUG(5, ("housekeeping\n"));
2455 change_to_root_user();
2457 /* update printer queue caches if necessary */
2458 update_monitored_printq_cache(sconn->msg_ctx);
2460 /* check if we need to reload services */
2461 check_reload(sconn, time_mono(NULL));
2463 /* Change machine password if neccessary. */
2464 attempt_machine_password_change();
2467 * Force a log file check.
2469 force_check_log_size();
2470 check_log_size();
2471 return true;
2475 * Read an smb packet in the echo handler child, giving the parent
2476 * smbd one second to react once the socket becomes readable.
2479 struct smbd_echo_read_state {
2480 struct tevent_context *ev;
2481 struct smbd_server_connection *sconn;
2483 char *buf;
2484 size_t buflen;
2485 uint32_t seqnum;
2488 static void smbd_echo_read_readable(struct tevent_req *subreq);
2489 static void smbd_echo_read_waited(struct tevent_req *subreq);
2491 static struct tevent_req *smbd_echo_read_send(
2492 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2493 struct smbd_server_connection *sconn)
2495 struct tevent_req *req, *subreq;
2496 struct smbd_echo_read_state *state;
2498 req = tevent_req_create(mem_ctx, &state,
2499 struct smbd_echo_read_state);
2500 if (req == NULL) {
2501 return NULL;
2503 state->ev = ev;
2504 state->sconn = sconn;
2506 subreq = wait_for_read_send(state, ev, sconn->sock);
2507 if (tevent_req_nomem(subreq, req)) {
2508 return tevent_req_post(req, ev);
2510 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2511 return req;
2514 static void smbd_echo_read_readable(struct tevent_req *subreq)
2516 struct tevent_req *req = tevent_req_callback_data(
2517 subreq, struct tevent_req);
2518 struct smbd_echo_read_state *state = tevent_req_data(
2519 req, struct smbd_echo_read_state);
2520 bool ok;
2521 int err;
2523 ok = wait_for_read_recv(subreq, &err);
2524 TALLOC_FREE(subreq);
2525 if (!ok) {
2526 tevent_req_nterror(req, map_nt_error_from_unix(err));
2527 return;
2531 * Give the parent smbd one second to step in
2534 subreq = tevent_wakeup_send(
2535 state, state->ev, timeval_current_ofs(1, 0));
2536 if (tevent_req_nomem(subreq, req)) {
2537 return;
2539 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2542 static void smbd_echo_read_waited(struct tevent_req *subreq)
2544 struct tevent_req *req = tevent_req_callback_data(
2545 subreq, struct tevent_req);
2546 struct smbd_echo_read_state *state = tevent_req_data(
2547 req, struct smbd_echo_read_state);
2548 struct smbd_server_connection *sconn = state->sconn;
2549 bool ok;
2550 NTSTATUS status;
2551 size_t unread = 0;
2552 bool encrypted;
2554 ok = tevent_wakeup_recv(subreq);
2555 TALLOC_FREE(subreq);
2556 if (!ok) {
2557 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2558 return;
2561 ok = smbd_lock_socket_internal(sconn);
2562 if (!ok) {
2563 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2564 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2565 return;
2568 if (!fd_is_readable(sconn->sock)) {
2569 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2570 (int)sys_getpid()));
2572 ok = smbd_unlock_socket_internal(sconn);
2573 if (!ok) {
2574 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2575 DEBUG(1, ("%s: failed to unlock socket\n",
2576 __location__));
2577 return;
2580 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2581 if (tevent_req_nomem(subreq, req)) {
2582 return;
2584 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2585 return;
2588 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2589 0 /* timeout */,
2590 &unread,
2591 &encrypted,
2592 &state->buflen,
2593 &state->seqnum,
2594 false /* trusted_channel*/);
2596 if (tevent_req_nterror(req, status)) {
2597 tevent_req_nterror(req, status);
2598 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2599 (int)sys_getpid(), nt_errstr(status)));
2600 return;
2603 ok = smbd_unlock_socket_internal(sconn);
2604 if (!ok) {
2605 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2606 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2607 return;
2609 tevent_req_done(req);
2612 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2613 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2615 struct smbd_echo_read_state *state = tevent_req_data(
2616 req, struct smbd_echo_read_state);
2617 NTSTATUS status;
2619 if (tevent_req_is_nterror(req, &status)) {
2620 return status;
2622 *pbuf = talloc_move(mem_ctx, &state->buf);
2623 *pbuflen = state->buflen;
2624 *pseqnum = state->seqnum;
2625 return NT_STATUS_OK;
2628 struct smbd_echo_state {
2629 struct tevent_context *ev;
2630 struct iovec *pending;
2631 struct smbd_server_connection *sconn;
2632 int parent_pipe;
2634 struct tevent_fd *parent_fde;
2636 struct tevent_req *write_req;
2639 static void smbd_echo_writer_done(struct tevent_req *req);
2641 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2643 int num_pending;
2645 if (state->write_req != NULL) {
2646 return;
2649 num_pending = talloc_array_length(state->pending);
2650 if (num_pending == 0) {
2651 return;
2654 state->write_req = writev_send(state, state->ev, NULL,
2655 state->parent_pipe, false,
2656 state->pending, num_pending);
2657 if (state->write_req == NULL) {
2658 DEBUG(1, ("writev_send failed\n"));
2659 exit(1);
2662 talloc_steal(state->write_req, state->pending);
2663 state->pending = NULL;
2665 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2666 state);
2669 static void smbd_echo_writer_done(struct tevent_req *req)
2671 struct smbd_echo_state *state = tevent_req_callback_data(
2672 req, struct smbd_echo_state);
2673 ssize_t written;
2674 int err;
2676 written = writev_recv(req, &err);
2677 TALLOC_FREE(req);
2678 state->write_req = NULL;
2679 if (written == -1) {
2680 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2681 exit(1);
2683 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2684 smbd_echo_activate_writer(state);
2687 static bool smbd_echo_reply(struct smbd_echo_state *state,
2688 uint8_t *inbuf, size_t inbuf_len,
2689 uint32_t seqnum)
2691 struct smb_request req;
2692 uint16_t num_replies;
2693 size_t out_len;
2694 char *outbuf;
2695 bool ok;
2697 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2698 DEBUG(10, ("Got netbios keepalive\n"));
2700 * Just swallow it
2702 return true;
2705 if (inbuf_len < smb_size) {
2706 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2707 return false;
2709 if (!valid_smb_header(state->sconn, inbuf)) {
2710 DEBUG(10, ("Got invalid SMB header\n"));
2711 return false;
2714 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2715 seqnum)) {
2716 return false;
2718 req.inbuf = inbuf;
2720 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2721 smb_messages[req.cmd].name
2722 ? smb_messages[req.cmd].name : "unknown"));
2724 if (req.cmd != SMBecho) {
2725 return false;
2727 if (req.wct < 1) {
2728 return false;
2731 num_replies = SVAL(req.vwv+0, 0);
2732 if (num_replies != 1) {
2733 /* Not a Windows "Hey, you're still there?" request */
2734 return false;
2737 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2738 1, req.buflen)) {
2739 DEBUG(10, ("create_outbuf failed\n"));
2740 return false;
2742 req.outbuf = (uint8_t *)outbuf;
2744 SSVAL(req.outbuf, smb_vwv0, num_replies);
2746 if (req.buflen > 0) {
2747 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2750 out_len = smb_len(req.outbuf) + 4;
2752 ok = srv_send_smb(req.sconn,
2753 (char *)outbuf,
2754 true, seqnum+1,
2755 false, &req.pcd);
2756 TALLOC_FREE(outbuf);
2757 if (!ok) {
2758 exit(1);
2761 return true;
2764 static void smbd_echo_exit(struct tevent_context *ev,
2765 struct tevent_fd *fde, uint16_t flags,
2766 void *private_data)
2768 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2769 exit(0);
2772 static void smbd_echo_got_packet(struct tevent_req *req);
2774 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2775 int parent_pipe)
2777 struct smbd_echo_state *state;
2778 struct tevent_req *read_req;
2780 state = talloc_zero(sconn, struct smbd_echo_state);
2781 if (state == NULL) {
2782 DEBUG(1, ("talloc failed\n"));
2783 return;
2785 state->sconn = sconn;
2786 state->parent_pipe = parent_pipe;
2787 state->ev = s3_tevent_context_init(state);
2788 if (state->ev == NULL) {
2789 DEBUG(1, ("tevent_context_init failed\n"));
2790 TALLOC_FREE(state);
2791 return;
2793 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2794 TEVENT_FD_READ, smbd_echo_exit,
2795 state);
2796 if (state->parent_fde == NULL) {
2797 DEBUG(1, ("tevent_add_fd failed\n"));
2798 TALLOC_FREE(state);
2799 return;
2802 read_req = smbd_echo_read_send(state, state->ev, sconn);
2803 if (read_req == NULL) {
2804 DEBUG(1, ("smbd_echo_read_send failed\n"));
2805 TALLOC_FREE(state);
2806 return;
2808 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2810 while (true) {
2811 if (tevent_loop_once(state->ev) == -1) {
2812 DEBUG(1, ("tevent_loop_once failed: %s\n",
2813 strerror(errno)));
2814 break;
2817 TALLOC_FREE(state);
2820 static void smbd_echo_got_packet(struct tevent_req *req)
2822 struct smbd_echo_state *state = tevent_req_callback_data(
2823 req, struct smbd_echo_state);
2824 NTSTATUS status;
2825 char *buf = NULL;
2826 size_t buflen = 0;
2827 uint32_t seqnum = 0;
2828 bool reply;
2830 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2831 TALLOC_FREE(req);
2832 if (!NT_STATUS_IS_OK(status)) {
2833 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2834 nt_errstr(status)));
2835 exit(1);
2838 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2839 if (!reply) {
2840 size_t num_pending;
2841 struct iovec *tmp;
2842 struct iovec *iov;
2844 num_pending = talloc_array_length(state->pending);
2845 tmp = talloc_realloc(state, state->pending, struct iovec,
2846 num_pending+1);
2847 if (tmp == NULL) {
2848 DEBUG(1, ("talloc_realloc failed\n"));
2849 exit(1);
2851 state->pending = tmp;
2853 if (buflen >= smb_size) {
2855 * place the seqnum in the packet so that the main process
2856 * can reply with signing
2858 SIVAL(buf, smb_ss_field, seqnum);
2859 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2862 iov = &state->pending[num_pending];
2863 iov->iov_base = buf;
2864 iov->iov_len = buflen;
2866 DEBUG(10,("echo_handler[%d]: forward to main\n",
2867 (int)sys_getpid()));
2868 smbd_echo_activate_writer(state);
2871 req = smbd_echo_read_send(state, state->ev, state->sconn);
2872 if (req == NULL) {
2873 DEBUG(1, ("smbd_echo_read_send failed\n"));
2874 exit(1);
2876 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2881 * Handle SMBecho requests in a forked child process
2883 bool fork_echo_handler(struct smbd_server_connection *sconn)
2885 int listener_pipe[2];
2886 int res;
2887 pid_t child;
2889 res = pipe(listener_pipe);
2890 if (res == -1) {
2891 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2892 return false;
2894 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2895 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2896 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2897 goto fail;
2900 child = sys_fork();
2901 if (child == 0) {
2902 NTSTATUS status;
2904 close(listener_pipe[0]);
2905 set_blocking(listener_pipe[1], false);
2907 status = reinit_after_fork(sconn->msg_ctx,
2908 sconn->ev_ctx,
2909 false);
2910 if (!NT_STATUS_IS_OK(status)) {
2911 DEBUG(1, ("reinit_after_fork failed: %s\n",
2912 nt_errstr(status)));
2913 exit(1);
2915 smbd_echo_loop(sconn, listener_pipe[1]);
2916 exit(0);
2918 close(listener_pipe[1]);
2919 listener_pipe[1] = -1;
2920 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2922 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2925 * Without smb signing this is the same as the normal smbd
2926 * listener. This needs to change once signing comes in.
2928 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2929 sconn,
2930 sconn->smb1.echo_handler.trusted_fd,
2931 TEVENT_FD_READ,
2932 smbd_server_echo_handler,
2933 sconn);
2934 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2935 DEBUG(1, ("event_add_fd failed\n"));
2936 goto fail;
2939 return true;
2941 fail:
2942 if (listener_pipe[0] != -1) {
2943 close(listener_pipe[0]);
2945 if (listener_pipe[1] != -1) {
2946 close(listener_pipe[1]);
2948 sconn->smb1.echo_handler.trusted_fd = -1;
2949 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2950 close(sconn->smb1.echo_handler.socket_lock_fd);
2952 sconn->smb1.echo_handler.trusted_fd = -1;
2953 sconn->smb1.echo_handler.socket_lock_fd = -1;
2954 return false;
2957 #if CLUSTER_SUPPORT
2959 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2960 struct sockaddr_storage *srv,
2961 struct sockaddr_storage *clnt)
2963 struct ctdbd_connection *cconn;
2964 char tmp_addr[INET6_ADDRSTRLEN];
2965 char *addr;
2967 cconn = messaging_ctdbd_connection();
2968 if (cconn == NULL) {
2969 return NT_STATUS_NO_MEMORY;
2972 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2973 addr = talloc_strdup(cconn, tmp_addr);
2974 if (addr == NULL) {
2975 return NT_STATUS_NO_MEMORY;
2977 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2980 #endif
2982 static bool uid_in_use(const struct user_struct *user, uid_t uid)
2984 while (user) {
2985 if (user->session_info &&
2986 (user->session_info->unix_token->uid == uid)) {
2987 return true;
2989 user = user->next;
2991 return false;
2994 static bool gid_in_use(const struct user_struct *user, gid_t gid)
2996 while (user) {
2997 if (user->session_info != NULL) {
2998 int i;
2999 struct security_unix_token *utok;
3001 utok = user->session_info->unix_token;
3002 if (utok->gid == gid) {
3003 return true;
3005 for(i=0; i<utok->ngroups; i++) {
3006 if (utok->groups[i] == gid) {
3007 return true;
3011 user = user->next;
3013 return false;
3016 static bool sid_in_use(const struct user_struct *user,
3017 const struct dom_sid *psid)
3019 while (user) {
3020 struct security_token *tok;
3022 if (user->session_info == NULL) {
3023 continue;
3025 tok = user->session_info->security_token;
3026 if (tok == NULL) {
3028 * Not sure session_info->security_token can
3029 * ever be NULL. This check might be not
3030 * necessary.
3032 continue;
3034 if (security_token_has_sid(tok, psid)) {
3035 return true;
3037 user = user->next;
3039 return false;
3042 static bool id_in_use(const struct user_struct *user,
3043 const struct id_cache_ref *id)
3045 switch(id->type) {
3046 case UID:
3047 return uid_in_use(user, id->id.uid);
3048 case GID:
3049 return gid_in_use(user, id->id.gid);
3050 case SID:
3051 return sid_in_use(user, &id->id.sid);
3052 default:
3053 break;
3055 return false;
3058 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3059 void *private_data,
3060 uint32_t msg_type,
3061 struct server_id server_id,
3062 DATA_BLOB* data)
3064 const char *msg = (data && data->data)
3065 ? (const char *)data->data : "<NULL>";
3066 struct user_struct *validated_users;
3067 struct id_cache_ref id;
3068 struct smbd_server_connection *sconn =
3069 talloc_get_type_abort(private_data,
3070 struct smbd_server_connection);
3072 validated_users = sconn->smb1.sessions.validated_users;
3074 if (!id_cache_ref_parse(msg, &id)) {
3075 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3076 return;
3079 if (id_in_use(validated_users, &id)) {
3080 exit_server_cleanly(msg);
3082 id_cache_delete_from_cache(&id);
3085 /****************************************************************************
3086 Process commands from the client
3087 ****************************************************************************/
3089 void smbd_process(struct tevent_context *ev_ctx,
3090 struct smbd_server_connection *sconn)
3092 TALLOC_CTX *frame = talloc_stackframe();
3093 struct sockaddr_storage ss;
3094 struct sockaddr *sa = NULL;
3095 socklen_t sa_socklen;
3096 struct tsocket_address *local_address = NULL;
3097 struct tsocket_address *remote_address = NULL;
3098 const char *locaddr = NULL;
3099 const char *remaddr = NULL;
3100 char *rhost;
3101 int ret;
3103 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
3105 * We're not making the decision here,
3106 * we're just allowing the client
3107 * to decide between SMB1 and SMB2
3108 * with the first negprot
3109 * packet.
3111 sconn->using_smb2 = true;
3114 /* Ensure child is set to blocking mode */
3115 set_blocking(sconn->sock,True);
3117 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3118 set_socket_options(sconn->sock, lp_socket_options());
3120 sa = (struct sockaddr *)(void *)&ss;
3121 sa_socklen = sizeof(ss);
3122 ret = getpeername(sconn->sock, sa, &sa_socklen);
3123 if (ret != 0) {
3124 int level = (errno == ENOTCONN)?2:0;
3125 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3126 exit_server_cleanly("getpeername() failed.\n");
3128 ret = tsocket_address_bsd_from_sockaddr(sconn,
3129 sa, sa_socklen,
3130 &remote_address);
3131 if (ret != 0) {
3132 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3133 __location__, strerror(errno)));
3134 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3137 sa = (struct sockaddr *)(void *)&ss;
3138 sa_socklen = sizeof(ss);
3139 ret = getsockname(sconn->sock, sa, &sa_socklen);
3140 if (ret != 0) {
3141 int level = (errno == ENOTCONN)?2:0;
3142 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3143 exit_server_cleanly("getsockname() failed.\n");
3145 ret = tsocket_address_bsd_from_sockaddr(sconn,
3146 sa, sa_socklen,
3147 &local_address);
3148 if (ret != 0) {
3149 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3150 __location__, strerror(errno)));
3151 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3154 sconn->local_address = local_address;
3155 sconn->remote_address = remote_address;
3157 if (tsocket_address_is_inet(local_address, "ip")) {
3158 locaddr = tsocket_address_inet_addr_string(
3159 sconn->local_address,
3160 talloc_tos());
3161 if (locaddr == NULL) {
3162 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3163 __location__, strerror(errno)));
3164 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3166 } else {
3167 locaddr = "0.0.0.0";
3170 if (tsocket_address_is_inet(remote_address, "ip")) {
3171 remaddr = tsocket_address_inet_addr_string(
3172 sconn->remote_address,
3173 talloc_tos());
3174 if (remaddr == NULL) {
3175 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3176 __location__, strerror(errno)));
3177 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3179 } else {
3180 remaddr = "0.0.0.0";
3183 /* this is needed so that we get decent entries
3184 in smbstatus for port 445 connects */
3185 set_remote_machine_name(remaddr, false);
3186 reload_services(sconn, conn_snum_used, true);
3189 * Before the first packet, check the global hosts allow/ hosts deny
3190 * parameters before doing any parsing of packets passed to us by the
3191 * client. This prevents attacks on our parsing code from hosts not in
3192 * the hosts allow list.
3195 ret = get_remote_hostname(remote_address,
3196 &rhost,
3197 talloc_tos());
3198 if (ret < 0) {
3199 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3200 __location__, strerror(errno)));
3201 exit_server_cleanly("get_remote_hostname failed.\n");
3203 if (strequal(rhost, "UNKNOWN")) {
3204 rhost = talloc_strdup(talloc_tos(), remaddr);
3206 sconn->remote_hostname = talloc_move(sconn, &rhost);
3208 sub_set_socket_ids(remaddr,
3209 sconn->remote_hostname,
3210 locaddr);
3212 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3213 sconn->remote_hostname,
3214 remaddr)) {
3216 * send a negative session response "not listening on calling
3217 * name"
3219 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3220 DEBUG( 1, ("Connection denied from %s to %s\n",
3221 tsocket_address_string(remote_address, talloc_tos()),
3222 tsocket_address_string(local_address, talloc_tos())));
3223 (void)srv_send_smb(sconn,(char *)buf, false,
3224 0, false, NULL);
3225 exit_server_cleanly("connection denied");
3228 DEBUG(10, ("Connection allowed from %s to %s\n",
3229 tsocket_address_string(remote_address, talloc_tos()),
3230 tsocket_address_string(local_address, talloc_tos())));
3232 init_modules();
3234 smb_perfcount_init();
3236 if (!init_account_policy()) {
3237 exit_server("Could not open account policy tdb.\n");
3240 if (*lp_rootdir()) {
3241 if (chroot(lp_rootdir()) != 0) {
3242 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3243 exit_server("Failed to chroot()");
3245 if (chdir("/") == -1) {
3246 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3247 exit_server("Failed to chroot()");
3249 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3252 if (!srv_init_signing(sconn)) {
3253 exit_server("Failed to init smb_signing");
3256 /* Setup oplocks */
3257 if (!init_oplocks(sconn))
3258 exit_server("Failed to init oplocks");
3260 /* register our message handlers */
3261 messaging_register(sconn->msg_ctx, sconn,
3262 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3263 messaging_register(sconn->msg_ctx, sconn,
3264 MSG_SMB_CLOSE_FILE, msg_close_file);
3265 messaging_register(sconn->msg_ctx, sconn,
3266 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3268 id_cache_register_msgs(sconn->msg_ctx);
3269 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3270 messaging_register(sconn->msg_ctx, sconn,
3271 ID_CACHE_KILL, smbd_id_cache_kill);
3273 messaging_deregister(sconn->msg_ctx,
3274 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3275 messaging_register(sconn->msg_ctx, sconn,
3276 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3279 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3280 * MSGs to all child processes
3282 messaging_deregister(sconn->msg_ctx,
3283 MSG_DEBUG, NULL);
3284 messaging_register(sconn->msg_ctx, NULL,
3285 MSG_DEBUG, debug_message);
3287 if ((lp_keepalive() != 0)
3288 && !(event_add_idle(ev_ctx, NULL,
3289 timeval_set(lp_keepalive(), 0),
3290 "keepalive", keepalive_fn,
3291 sconn))) {
3292 DEBUG(0, ("Could not add keepalive event\n"));
3293 exit(1);
3296 if (!(event_add_idle(ev_ctx, NULL,
3297 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3298 "deadtime", deadtime_fn, sconn))) {
3299 DEBUG(0, ("Could not add deadtime event\n"));
3300 exit(1);
3303 if (!(event_add_idle(ev_ctx, NULL,
3304 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3305 "housekeeping", housekeeping_fn, sconn))) {
3306 DEBUG(0, ("Could not add housekeeping event\n"));
3307 exit(1);
3310 #ifdef CLUSTER_SUPPORT
3312 if (lp_clustering()) {
3314 * We need to tell ctdb about our client's TCP
3315 * connection, so that for failover ctdbd can send
3316 * tickle acks, triggering a reconnection by the
3317 * client.
3320 struct sockaddr_storage srv, clnt;
3322 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3323 NTSTATUS status;
3324 status = smbd_register_ips(sconn, &srv, &clnt);
3325 if (!NT_STATUS_IS_OK(status)) {
3326 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3327 nt_errstr(status)));
3329 } else
3331 DEBUG(0,("Unable to get tcp info for "
3332 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3333 strerror(errno)));
3337 #endif
3339 sconn->nbt.got_session = false;
3341 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3343 sconn->smb1.sessions.done_sesssetup = false;
3344 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3345 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3346 /* users from session setup */
3347 sconn->smb1.sessions.session_userlist = NULL;
3348 /* workgroup from session setup. */
3349 sconn->smb1.sessions.session_workgroup = NULL;
3350 /* this holds info on user ids that are already validated for this VC */
3351 sconn->smb1.sessions.validated_users = NULL;
3352 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3353 sconn->smb1.sessions.num_validated_vuids = 0;
3355 conn_init(sconn);
3356 if (!init_dptrs(sconn)) {
3357 exit_server("init_dptrs() failed");
3360 sconn->smb1.fde = event_add_fd(ev_ctx,
3361 sconn,
3362 sconn->sock,
3363 EVENT_FD_READ,
3364 smbd_server_connection_handler,
3365 sconn);
3366 if (!sconn->smb1.fde) {
3367 exit_server("failed to create smbd_server_connection fde");
3370 TALLOC_FREE(frame);
3372 while (True) {
3373 NTSTATUS status;
3375 frame = talloc_stackframe_pool(8192);
3377 errno = 0;
3379 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3380 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3381 !NT_STATUS_IS_OK(status)) {
3382 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3383 " exiting\n", nt_errstr(status)));
3384 break;
3387 TALLOC_FREE(frame);
3390 exit_server_cleanly(NULL);
3393 bool req_is_in_chain(struct smb_request *req)
3395 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3397 * We're right now handling a subsequent request, so we must
3398 * be in a chain
3400 return true;
3403 if (!is_andx_req(req->cmd)) {
3404 return false;
3407 if (req->wct < 2) {
3409 * Okay, an illegal request, but definitely not chained :-)
3411 return false;
3414 return (CVAL(req->vwv+0, 0) != 0xFF);