s3-rpc_server: Move the endpoint registration to own file.
[Samba/vl.git] / source3 / smbd / process.c
blob9df95a8d9dd091f5f2e384c0a6851d756468db94
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/pcap.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
40 extern bool global_machine_password_needs_changing;
42 static void construct_reply_common(struct smb_request *req, const char *inbuf,
43 char *outbuf);
44 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
46 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
48 bool ok;
50 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
51 return true;
54 sconn->smb1.echo_handler.ref_count++;
56 if (sconn->smb1.echo_handler.ref_count > 1) {
57 return true;
60 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
62 do {
63 ok = fcntl_lock(
64 sconn->smb1.echo_handler.socket_lock_fd,
65 SMB_F_SETLKW, 0, 0, F_WRLCK);
66 } while (!ok && (errno == EINTR));
68 if (!ok) {
69 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
70 return false;
73 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
75 return true;
78 void smbd_lock_socket(struct smbd_server_connection *sconn)
80 if (!smbd_lock_socket_internal(sconn)) {
81 exit_server_cleanly("failed to lock socket");
85 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
87 bool ok;
89 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
90 return true;
93 sconn->smb1.echo_handler.ref_count--;
95 if (sconn->smb1.echo_handler.ref_count > 0) {
96 return true;
99 do {
100 ok = fcntl_lock(
101 sconn->smb1.echo_handler.socket_lock_fd,
102 SMB_F_SETLKW, 0, 0, F_UNLCK);
103 } while (!ok && (errno == EINTR));
105 if (!ok) {
106 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
107 return false;
110 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
112 return true;
115 void smbd_unlock_socket(struct smbd_server_connection *sconn)
117 if (!smbd_unlock_socket_internal(sconn)) {
118 exit_server_cleanly("failed to unlock socket");
122 /* Accessor function for smb_read_error for smbd functions. */
124 /****************************************************************************
125 Send an smb to a fd.
126 ****************************************************************************/
128 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
129 bool do_signing, uint32_t seqnum,
130 bool do_encrypt,
131 struct smb_perfcount_data *pcd)
133 size_t len = 0;
134 size_t nwritten=0;
135 ssize_t ret;
136 char *buf_out = buffer;
138 smbd_lock_socket(sconn);
140 if (do_signing) {
141 /* Sign the outgoing packet if required. */
142 srv_calculate_sign_mac(sconn, buf_out, seqnum);
145 if (do_encrypt) {
146 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
147 if (!NT_STATUS_IS_OK(status)) {
148 DEBUG(0, ("send_smb: SMB encryption failed "
149 "on outgoing packet! Error %s\n",
150 nt_errstr(status) ));
151 goto out;
155 len = smb_len(buf_out) + 4;
157 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
158 if (ret <= 0) {
160 char addr[INET6_ADDRSTRLEN];
162 * Try and give an error message saying what
163 * client failed.
165 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
166 (int)sys_getpid(), (int)len,
167 get_peer_addr(sconn->sock, addr, sizeof(addr)),
168 (int)ret, strerror(errno) ));
170 srv_free_enc_buffer(buf_out);
171 goto out;
174 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
175 srv_free_enc_buffer(buf_out);
176 out:
177 SMB_PERFCOUNT_END(pcd);
179 smbd_unlock_socket(sconn);
180 return true;
183 /*******************************************************************
184 Setup the word count and byte count for a smb message.
185 ********************************************************************/
187 int srv_set_message(char *buf,
188 int num_words,
189 int num_bytes,
190 bool zero)
192 if (zero && (num_words || num_bytes)) {
193 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
195 SCVAL(buf,smb_wct,num_words);
196 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
197 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
198 return (smb_size + num_words*2 + num_bytes);
201 static bool valid_smb_header(const uint8_t *inbuf)
203 if (is_encrypted_packet(inbuf)) {
204 return true;
207 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
208 * but it just looks weird to call strncmp for this one.
210 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
213 /* Socket functions for smbd packet processing. */
215 static bool valid_packet_size(size_t len)
218 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
219 * of header. Don't print the error if this fits.... JRA.
222 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
223 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
224 (unsigned long)len));
225 return false;
227 return true;
230 static NTSTATUS read_packet_remainder(int fd, char *buffer,
231 unsigned int timeout, ssize_t len)
233 NTSTATUS status;
235 if (len <= 0) {
236 return NT_STATUS_OK;
239 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
240 if (!NT_STATUS_IS_OK(status)) {
241 char addr[INET6_ADDRSTRLEN];
242 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
243 "error = %s.\n",
244 get_peer_addr(fd, addr, sizeof(addr)),
245 nt_errstr(status)));
247 return status;
250 /****************************************************************************
251 Attempt a zerocopy writeX read. We know here that len > smb_size-4
252 ****************************************************************************/
255 * Unfortunately, earlier versions of smbclient/libsmbclient
256 * don't send this "standard" writeX header. I've fixed this
257 * for 3.2 but we'll use the old method with earlier versions.
258 * Windows and CIFSFS at least use this standard size. Not
259 * sure about MacOSX.
262 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
263 (2*14) + /* word count (including bcc) */ \
264 1 /* pad byte */)
266 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
267 const char lenbuf[4],
268 struct smbd_server_connection *sconn,
269 int sock,
270 char **buffer,
271 unsigned int timeout,
272 size_t *p_unread,
273 size_t *len_ret)
275 /* Size of a WRITEX call (+4 byte len). */
276 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
277 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
278 ssize_t toread;
279 NTSTATUS status;
281 memcpy(writeX_header, lenbuf, 4);
283 status = read_fd_with_timeout(
284 sock, writeX_header + 4,
285 STANDARD_WRITE_AND_X_HEADER_SIZE,
286 STANDARD_WRITE_AND_X_HEADER_SIZE,
287 timeout, NULL);
289 if (!NT_STATUS_IS_OK(status)) {
290 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
291 "error = %s.\n",
292 tsocket_address_string(sconn->remote_address,
293 talloc_tos()),
294 nt_errstr(status)));
295 return status;
299 * Ok - now try and see if this is a possible
300 * valid writeX call.
303 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
305 * If the data offset is beyond what
306 * we've read, drain the extra bytes.
308 uint16_t doff = SVAL(writeX_header,smb_vwv11);
309 ssize_t newlen;
311 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
312 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
313 if (drain_socket(sock, drain) != drain) {
314 smb_panic("receive_smb_raw_talloc_partial_read:"
315 " failed to drain pending bytes");
317 } else {
318 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
321 /* Spoof down the length and null out the bcc. */
322 set_message_bcc(writeX_header, 0);
323 newlen = smb_len(writeX_header);
325 /* Copy the header we've written. */
327 *buffer = (char *)talloc_memdup(mem_ctx,
328 writeX_header,
329 sizeof(writeX_header));
331 if (*buffer == NULL) {
332 DEBUG(0, ("Could not allocate inbuf of length %d\n",
333 (int)sizeof(writeX_header)));
334 return NT_STATUS_NO_MEMORY;
337 /* Work out the remaining bytes. */
338 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
339 *len_ret = newlen + 4;
340 return NT_STATUS_OK;
343 if (!valid_packet_size(len)) {
344 return NT_STATUS_INVALID_PARAMETER;
348 * Not a valid writeX call. Just do the standard
349 * talloc and return.
352 *buffer = talloc_array(mem_ctx, char, len+4);
354 if (*buffer == NULL) {
355 DEBUG(0, ("Could not allocate inbuf of length %d\n",
356 (int)len+4));
357 return NT_STATUS_NO_MEMORY;
360 /* Copy in what we already read. */
361 memcpy(*buffer,
362 writeX_header,
363 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
364 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
366 if(toread > 0) {
367 status = read_packet_remainder(
368 sock,
369 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
370 timeout, toread);
372 if (!NT_STATUS_IS_OK(status)) {
373 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
374 nt_errstr(status)));
375 return status;
379 *len_ret = len + 4;
380 return NT_STATUS_OK;
383 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
384 struct smbd_server_connection *sconn,
385 int sock,
386 char **buffer, unsigned int timeout,
387 size_t *p_unread, size_t *plen)
389 char lenbuf[4];
390 size_t len;
391 int min_recv_size = lp_min_receive_file_size();
392 NTSTATUS status;
394 *p_unread = 0;
396 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
397 &len);
398 if (!NT_STATUS_IS_OK(status)) {
399 return status;
402 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
403 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
404 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
405 !srv_is_signing_active(sconn) &&
406 sconn->smb1.echo_handler.trusted_fde == NULL) {
408 return receive_smb_raw_talloc_partial_read(
409 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
410 p_unread, plen);
413 if (!valid_packet_size(len)) {
414 return NT_STATUS_INVALID_PARAMETER;
418 * The +4 here can't wrap, we've checked the length above already.
421 *buffer = talloc_array(mem_ctx, char, len+4);
423 if (*buffer == NULL) {
424 DEBUG(0, ("Could not allocate inbuf of length %d\n",
425 (int)len+4));
426 return NT_STATUS_NO_MEMORY;
429 memcpy(*buffer, lenbuf, sizeof(lenbuf));
431 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
432 if (!NT_STATUS_IS_OK(status)) {
433 return status;
436 *plen = len + 4;
437 return NT_STATUS_OK;
440 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
441 struct smbd_server_connection *sconn,
442 int sock,
443 char **buffer, unsigned int timeout,
444 size_t *p_unread, bool *p_encrypted,
445 size_t *p_len,
446 uint32_t *seqnum,
447 bool trusted_channel)
449 size_t len = 0;
450 NTSTATUS status;
452 *p_encrypted = false;
454 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
455 p_unread, &len);
456 if (!NT_STATUS_IS_OK(status)) {
457 DEBUG(1, ("read_smb_length_return_keepalive failed for "
458 "client %s read error = %s.\n",
459 tsocket_address_string(sconn->remote_address,
460 talloc_tos()),
461 nt_errstr(status)));
462 return status;
465 if (is_encrypted_packet((uint8_t *)*buffer)) {
466 status = srv_decrypt_buffer(*buffer);
467 if (!NT_STATUS_IS_OK(status)) {
468 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
469 "incoming packet! Error %s\n",
470 nt_errstr(status) ));
471 return status;
473 *p_encrypted = true;
476 /* Check the incoming SMB signature. */
477 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
478 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
479 "incoming packet!\n"));
480 return NT_STATUS_INVALID_NETWORK_RESPONSE;
483 *p_len = len;
484 return NT_STATUS_OK;
488 * Initialize a struct smb_request from an inbuf
491 static bool init_smb_request(struct smb_request *req,
492 struct smbd_server_connection *sconn,
493 const uint8 *inbuf,
494 size_t unread_bytes, bool encrypted,
495 uint32_t seqnum)
497 size_t req_size = smb_len(inbuf) + 4;
498 /* Ensure we have at least smb_size bytes. */
499 if (req_size < smb_size) {
500 DEBUG(0,("init_smb_request: invalid request size %u\n",
501 (unsigned int)req_size ));
502 return false;
504 req->cmd = CVAL(inbuf, smb_com);
505 req->flags2 = SVAL(inbuf, smb_flg2);
506 req->smbpid = SVAL(inbuf, smb_pid);
507 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
508 req->seqnum = seqnum;
509 req->vuid = SVAL(inbuf, smb_uid);
510 req->tid = SVAL(inbuf, smb_tid);
511 req->wct = CVAL(inbuf, smb_wct);
512 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
513 req->buflen = smb_buflen(inbuf);
514 req->buf = (const uint8_t *)smb_buf_const(inbuf);
515 req->unread_bytes = unread_bytes;
516 req->encrypted = encrypted;
517 req->sconn = sconn;
518 req->conn = conn_find(sconn,req->tid);
519 req->chain_fsp = NULL;
520 req->chain_outbuf = NULL;
521 req->done = false;
522 req->smb2req = NULL;
523 smb_init_perfcount_data(&req->pcd);
525 /* Ensure we have at least wct words and 2 bytes of bcc. */
526 if (smb_size + req->wct*2 > req_size) {
527 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
528 (unsigned int)req->wct,
529 (unsigned int)req_size));
530 return false;
532 /* Ensure bcc is correct. */
533 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
534 DEBUG(0,("init_smb_request: invalid bcc number %u "
535 "(wct = %u, size %u)\n",
536 (unsigned int)req->buflen,
537 (unsigned int)req->wct,
538 (unsigned int)req_size));
539 return false;
542 req->outbuf = NULL;
543 return true;
546 static void process_smb(struct smbd_server_connection *conn,
547 uint8_t *inbuf, size_t nread, size_t unread_bytes,
548 uint32_t seqnum, bool encrypted,
549 struct smb_perfcount_data *deferred_pcd);
551 static void smbd_deferred_open_timer(struct event_context *ev,
552 struct timed_event *te,
553 struct timeval _tval,
554 void *private_data)
556 struct pending_message_list *msg = talloc_get_type(private_data,
557 struct pending_message_list);
558 TALLOC_CTX *mem_ctx = talloc_tos();
559 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
560 uint8_t *inbuf;
562 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
563 msg->buf.length);
564 if (inbuf == NULL) {
565 exit_server("smbd_deferred_open_timer: talloc failed\n");
566 return;
569 /* We leave this message on the queue so the open code can
570 know this is a retry. */
571 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
572 (unsigned long long)mid ));
574 /* Mark the message as processed so this is not
575 * re-processed in error. */
576 msg->processed = true;
578 process_smb(smbd_server_conn, inbuf,
579 msg->buf.length, 0,
580 msg->seqnum, msg->encrypted, &msg->pcd);
582 /* If it's still there and was processed, remove it. */
583 msg = get_deferred_open_message_smb(mid);
584 if (msg && msg->processed) {
585 remove_deferred_open_message_smb(mid);
589 /****************************************************************************
590 Function to push a message onto the tail of a linked list of smb messages ready
591 for processing.
592 ****************************************************************************/
594 static bool push_queued_message(struct smb_request *req,
595 struct timeval request_time,
596 struct timeval end_time,
597 char *private_data, size_t private_len)
599 int msg_len = smb_len(req->inbuf) + 4;
600 struct pending_message_list *msg;
602 msg = talloc_zero(NULL, struct pending_message_list);
604 if(msg == NULL) {
605 DEBUG(0,("push_message: malloc fail (1)\n"));
606 return False;
609 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
610 if(msg->buf.data == NULL) {
611 DEBUG(0,("push_message: malloc fail (2)\n"));
612 TALLOC_FREE(msg);
613 return False;
616 msg->request_time = request_time;
617 msg->seqnum = req->seqnum;
618 msg->encrypted = req->encrypted;
619 msg->processed = false;
620 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
622 if (private_data) {
623 msg->private_data = data_blob_talloc(msg, private_data,
624 private_len);
625 if (msg->private_data.data == NULL) {
626 DEBUG(0,("push_message: malloc fail (3)\n"));
627 TALLOC_FREE(msg);
628 return False;
632 msg->te = event_add_timed(server_event_context(),
633 msg,
634 end_time,
635 smbd_deferred_open_timer,
636 msg);
637 if (!msg->te) {
638 DEBUG(0,("push_message: event_add_timed failed\n"));
639 TALLOC_FREE(msg);
640 return false;
643 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
645 DEBUG(10,("push_message: pushed message length %u on "
646 "deferred_open_queue\n", (unsigned int)msg_len));
648 return True;
651 /****************************************************************************
652 Function to delete a sharing violation open message by mid.
653 ****************************************************************************/
655 void remove_deferred_open_message_smb(uint64_t mid)
657 struct pending_message_list *pml;
659 if (smbd_server_conn->using_smb2) {
660 remove_deferred_open_message_smb2(smbd_server_conn, mid);
661 return;
664 for (pml = deferred_open_queue; pml; pml = pml->next) {
665 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
666 DEBUG(10,("remove_deferred_open_message_smb: "
667 "deleting mid %llu len %u\n",
668 (unsigned long long)mid,
669 (unsigned int)pml->buf.length ));
670 DLIST_REMOVE(deferred_open_queue, pml);
671 TALLOC_FREE(pml);
672 return;
677 /****************************************************************************
678 Move a sharing violation open retry message to the front of the list and
679 schedule it for immediate processing.
680 ****************************************************************************/
682 void schedule_deferred_open_message_smb(uint64_t mid)
684 struct pending_message_list *pml;
685 int i = 0;
687 if (smbd_server_conn->using_smb2) {
688 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
689 return;
692 for (pml = deferred_open_queue; pml; pml = pml->next) {
693 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
695 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
696 "msg_mid = %llu\n",
697 i++,
698 (unsigned long long)msg_mid ));
700 if (mid == msg_mid) {
701 struct timed_event *te;
703 if (pml->processed) {
704 /* A processed message should not be
705 * rescheduled. */
706 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
707 "message mid %llu was already processed\n",
708 (unsigned long long)msg_mid ));
709 continue;
712 DEBUG(10,("schedule_deferred_open_message_smb: "
713 "scheduling mid %llu\n",
714 (unsigned long long)mid ));
716 te = event_add_timed(server_event_context(),
717 pml,
718 timeval_zero(),
719 smbd_deferred_open_timer,
720 pml);
721 if (!te) {
722 DEBUG(10,("schedule_deferred_open_message_smb: "
723 "event_add_timed() failed, "
724 "skipping mid %llu\n",
725 (unsigned long long)msg_mid ));
728 TALLOC_FREE(pml->te);
729 pml->te = te;
730 DLIST_PROMOTE(deferred_open_queue, pml);
731 return;
735 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
736 "find message mid %llu\n",
737 (unsigned long long)mid ));
740 /****************************************************************************
741 Return true if this mid is on the deferred queue and was not yet processed.
742 ****************************************************************************/
744 bool open_was_deferred(uint64_t mid)
746 struct pending_message_list *pml;
748 if (smbd_server_conn->using_smb2) {
749 return open_was_deferred_smb2(smbd_server_conn, mid);
752 for (pml = deferred_open_queue; pml; pml = pml->next) {
753 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
754 return True;
757 return False;
760 /****************************************************************************
761 Return the message queued by this mid.
762 ****************************************************************************/
764 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
766 struct pending_message_list *pml;
768 for (pml = deferred_open_queue; pml; pml = pml->next) {
769 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
770 return pml;
773 return NULL;
776 /****************************************************************************
777 Get the state data queued by this mid.
778 ****************************************************************************/
780 bool get_deferred_open_message_state(struct smb_request *smbreq,
781 struct timeval *p_request_time,
782 void **pp_state)
784 struct pending_message_list *pml;
786 if (smbd_server_conn->using_smb2) {
787 return get_deferred_open_message_state_smb2(smbreq->smb2req,
788 p_request_time,
789 pp_state);
792 pml = get_deferred_open_message_smb(smbreq->mid);
793 if (!pml) {
794 return false;
796 if (p_request_time) {
797 *p_request_time = pml->request_time;
799 if (pp_state) {
800 *pp_state = (void *)pml->private_data.data;
802 return true;
805 /****************************************************************************
806 Function to push a deferred open smb message onto a linked list of local smb
807 messages ready for processing.
808 ****************************************************************************/
810 bool push_deferred_open_message_smb(struct smb_request *req,
811 struct timeval request_time,
812 struct timeval timeout,
813 struct file_id id,
814 char *private_data, size_t priv_len)
816 struct timeval end_time;
818 if (req->smb2req) {
819 return push_deferred_open_message_smb2(req->smb2req,
820 request_time,
821 timeout,
823 private_data,
824 priv_len);
827 if (req->unread_bytes) {
828 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
829 "unread_bytes = %u\n",
830 (unsigned int)req->unread_bytes ));
831 smb_panic("push_deferred_open_message_smb: "
832 "logic error unread_bytes != 0" );
835 end_time = timeval_sum(&request_time, &timeout);
837 DEBUG(10,("push_deferred_open_message_smb: pushing message "
838 "len %u mid %llu timeout time [%u.%06u]\n",
839 (unsigned int) smb_len(req->inbuf)+4,
840 (unsigned long long)req->mid,
841 (unsigned int)end_time.tv_sec,
842 (unsigned int)end_time.tv_usec));
844 return push_queued_message(req, request_time, end_time,
845 private_data, priv_len);
848 static void smbd_sig_term_handler(struct tevent_context *ev,
849 struct tevent_signal *se,
850 int signum,
851 int count,
852 void *siginfo,
853 void *private_data)
855 exit_server_cleanly("termination signal");
858 void smbd_setup_sig_term_handler(void)
860 struct tevent_signal *se;
862 se = tevent_add_signal(server_event_context(),
863 server_event_context(),
864 SIGTERM, 0,
865 smbd_sig_term_handler,
866 NULL);
867 if (!se) {
868 exit_server("failed to setup SIGTERM handler");
872 static void smbd_sig_hup_handler(struct tevent_context *ev,
873 struct tevent_signal *se,
874 int signum,
875 int count,
876 void *siginfo,
877 void *private_data)
879 struct messaging_context *msg_ctx = talloc_get_type_abort(
880 private_data, struct messaging_context);
881 change_to_root_user();
882 DEBUG(1,("Reloading services after SIGHUP\n"));
883 reload_services(msg_ctx, smbd_server_conn->sock, False);
884 if (am_parent) {
885 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
889 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
890 struct messaging_context *msg_ctx)
892 struct tevent_signal *se;
894 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
895 msg_ctx);
896 if (!se) {
897 exit_server("failed to setup SIGHUP handler");
901 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
903 int timeout;
904 int num_pfds = 0;
905 int ret;
906 bool retry;
908 timeout = SMBD_SELECT_TIMEOUT * 1000;
911 * Are there any timed events waiting ? If so, ensure we don't
912 * select for longer than it would take to wait for them.
915 event_add_to_poll_args(server_event_context(), conn,
916 &conn->pfds, &num_pfds, &timeout);
918 /* Process a signal and timed events now... */
919 if (run_events_poll(server_event_context(), 0, NULL, 0)) {
920 return NT_STATUS_RETRY;
924 int sav;
925 START_PROFILE(smbd_idle);
927 ret = sys_poll(conn->pfds, num_pfds, timeout);
928 sav = errno;
930 END_PROFILE(smbd_idle);
931 errno = sav;
934 if (ret == -1) {
935 if (errno == EINTR) {
936 return NT_STATUS_RETRY;
938 return map_nt_error_from_unix(errno);
941 retry = run_events_poll(server_event_context(), ret, conn->pfds,
942 num_pfds);
943 if (retry) {
944 return NT_STATUS_RETRY;
947 /* Did we timeout ? */
948 if (ret == 0) {
949 return NT_STATUS_RETRY;
952 /* should not be reached */
953 return NT_STATUS_INTERNAL_ERROR;
957 * Only allow 5 outstanding trans requests. We're allocating memory, so
958 * prevent a DoS.
961 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
963 int count = 0;
964 for (; list != NULL; list = list->next) {
966 if (list->mid == mid) {
967 return NT_STATUS_INVALID_PARAMETER;
970 count += 1;
972 if (count > 5) {
973 return NT_STATUS_INSUFFICIENT_RESOURCES;
976 return NT_STATUS_OK;
980 These flags determine some of the permissions required to do an operation
982 Note that I don't set NEED_WRITE on some write operations because they
983 are used by some brain-dead clients when printing, and I don't want to
984 force write permissions on print services.
986 #define AS_USER (1<<0)
987 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
988 #define TIME_INIT (1<<2)
989 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
990 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
991 #define DO_CHDIR (1<<6)
994 define a list of possible SMB messages and their corresponding
995 functions. Any message that has a NULL function is unimplemented -
996 please feel free to contribute implementations!
998 static const struct smb_message_struct {
999 const char *name;
1000 void (*fn)(struct smb_request *req);
1001 int flags;
1002 } smb_messages[256] = {
1004 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1005 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1006 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1007 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1008 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1009 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1010 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1011 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1012 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1013 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1014 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1015 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1016 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1017 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1018 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1019 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1020 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1021 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1022 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1023 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1024 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1025 /* 0x15 */ { NULL, NULL, 0 },
1026 /* 0x16 */ { NULL, NULL, 0 },
1027 /* 0x17 */ { NULL, NULL, 0 },
1028 /* 0x18 */ { NULL, NULL, 0 },
1029 /* 0x19 */ { NULL, NULL, 0 },
1030 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1031 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1032 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1033 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1034 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1035 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1036 /* 0x20 */ { "SMBwritec", NULL,0},
1037 /* 0x21 */ { NULL, NULL, 0 },
1038 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1039 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1040 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1041 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1042 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1043 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1044 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1045 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1046 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1047 /* 0x2b */ { "SMBecho",reply_echo,0},
1048 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1049 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1050 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1051 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1052 /* 0x30 */ { NULL, NULL, 0 },
1053 /* 0x31 */ { NULL, NULL, 0 },
1054 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1055 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1056 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1057 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1058 /* 0x36 */ { NULL, NULL, 0 },
1059 /* 0x37 */ { NULL, NULL, 0 },
1060 /* 0x38 */ { NULL, NULL, 0 },
1061 /* 0x39 */ { NULL, NULL, 0 },
1062 /* 0x3a */ { NULL, NULL, 0 },
1063 /* 0x3b */ { NULL, NULL, 0 },
1064 /* 0x3c */ { NULL, NULL, 0 },
1065 /* 0x3d */ { NULL, NULL, 0 },
1066 /* 0x3e */ { NULL, NULL, 0 },
1067 /* 0x3f */ { NULL, NULL, 0 },
1068 /* 0x40 */ { NULL, NULL, 0 },
1069 /* 0x41 */ { NULL, NULL, 0 },
1070 /* 0x42 */ { NULL, NULL, 0 },
1071 /* 0x43 */ { NULL, NULL, 0 },
1072 /* 0x44 */ { NULL, NULL, 0 },
1073 /* 0x45 */ { NULL, NULL, 0 },
1074 /* 0x46 */ { NULL, NULL, 0 },
1075 /* 0x47 */ { NULL, NULL, 0 },
1076 /* 0x48 */ { NULL, NULL, 0 },
1077 /* 0x49 */ { NULL, NULL, 0 },
1078 /* 0x4a */ { NULL, NULL, 0 },
1079 /* 0x4b */ { NULL, NULL, 0 },
1080 /* 0x4c */ { NULL, NULL, 0 },
1081 /* 0x4d */ { NULL, NULL, 0 },
1082 /* 0x4e */ { NULL, NULL, 0 },
1083 /* 0x4f */ { NULL, NULL, 0 },
1084 /* 0x50 */ { NULL, NULL, 0 },
1085 /* 0x51 */ { NULL, NULL, 0 },
1086 /* 0x52 */ { NULL, NULL, 0 },
1087 /* 0x53 */ { NULL, NULL, 0 },
1088 /* 0x54 */ { NULL, NULL, 0 },
1089 /* 0x55 */ { NULL, NULL, 0 },
1090 /* 0x56 */ { NULL, NULL, 0 },
1091 /* 0x57 */ { NULL, NULL, 0 },
1092 /* 0x58 */ { NULL, NULL, 0 },
1093 /* 0x59 */ { NULL, NULL, 0 },
1094 /* 0x5a */ { NULL, NULL, 0 },
1095 /* 0x5b */ { NULL, NULL, 0 },
1096 /* 0x5c */ { NULL, NULL, 0 },
1097 /* 0x5d */ { NULL, NULL, 0 },
1098 /* 0x5e */ { NULL, NULL, 0 },
1099 /* 0x5f */ { NULL, NULL, 0 },
1100 /* 0x60 */ { NULL, NULL, 0 },
1101 /* 0x61 */ { NULL, NULL, 0 },
1102 /* 0x62 */ { NULL, NULL, 0 },
1103 /* 0x63 */ { NULL, NULL, 0 },
1104 /* 0x64 */ { NULL, NULL, 0 },
1105 /* 0x65 */ { NULL, NULL, 0 },
1106 /* 0x66 */ { NULL, NULL, 0 },
1107 /* 0x67 */ { NULL, NULL, 0 },
1108 /* 0x68 */ { NULL, NULL, 0 },
1109 /* 0x69 */ { NULL, NULL, 0 },
1110 /* 0x6a */ { NULL, NULL, 0 },
1111 /* 0x6b */ { NULL, NULL, 0 },
1112 /* 0x6c */ { NULL, NULL, 0 },
1113 /* 0x6d */ { NULL, NULL, 0 },
1114 /* 0x6e */ { NULL, NULL, 0 },
1115 /* 0x6f */ { NULL, NULL, 0 },
1116 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1117 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1118 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1119 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1120 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1121 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1122 /* 0x76 */ { NULL, NULL, 0 },
1123 /* 0x77 */ { NULL, NULL, 0 },
1124 /* 0x78 */ { NULL, NULL, 0 },
1125 /* 0x79 */ { NULL, NULL, 0 },
1126 /* 0x7a */ { NULL, NULL, 0 },
1127 /* 0x7b */ { NULL, NULL, 0 },
1128 /* 0x7c */ { NULL, NULL, 0 },
1129 /* 0x7d */ { NULL, NULL, 0 },
1130 /* 0x7e */ { NULL, NULL, 0 },
1131 /* 0x7f */ { NULL, NULL, 0 },
1132 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1133 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1134 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1135 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1136 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1137 /* 0x85 */ { NULL, NULL, 0 },
1138 /* 0x86 */ { NULL, NULL, 0 },
1139 /* 0x87 */ { NULL, NULL, 0 },
1140 /* 0x88 */ { NULL, NULL, 0 },
1141 /* 0x89 */ { NULL, NULL, 0 },
1142 /* 0x8a */ { NULL, NULL, 0 },
1143 /* 0x8b */ { NULL, NULL, 0 },
1144 /* 0x8c */ { NULL, NULL, 0 },
1145 /* 0x8d */ { NULL, NULL, 0 },
1146 /* 0x8e */ { NULL, NULL, 0 },
1147 /* 0x8f */ { NULL, NULL, 0 },
1148 /* 0x90 */ { NULL, NULL, 0 },
1149 /* 0x91 */ { NULL, NULL, 0 },
1150 /* 0x92 */ { NULL, NULL, 0 },
1151 /* 0x93 */ { NULL, NULL, 0 },
1152 /* 0x94 */ { NULL, NULL, 0 },
1153 /* 0x95 */ { NULL, NULL, 0 },
1154 /* 0x96 */ { NULL, NULL, 0 },
1155 /* 0x97 */ { NULL, NULL, 0 },
1156 /* 0x98 */ { NULL, NULL, 0 },
1157 /* 0x99 */ { NULL, NULL, 0 },
1158 /* 0x9a */ { NULL, NULL, 0 },
1159 /* 0x9b */ { NULL, NULL, 0 },
1160 /* 0x9c */ { NULL, NULL, 0 },
1161 /* 0x9d */ { NULL, NULL, 0 },
1162 /* 0x9e */ { NULL, NULL, 0 },
1163 /* 0x9f */ { NULL, NULL, 0 },
1164 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1165 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1166 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1167 /* 0xa3 */ { NULL, NULL, 0 },
1168 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1169 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1170 /* 0xa6 */ { NULL, NULL, 0 },
1171 /* 0xa7 */ { NULL, NULL, 0 },
1172 /* 0xa8 */ { NULL, NULL, 0 },
1173 /* 0xa9 */ { NULL, NULL, 0 },
1174 /* 0xaa */ { NULL, NULL, 0 },
1175 /* 0xab */ { NULL, NULL, 0 },
1176 /* 0xac */ { NULL, NULL, 0 },
1177 /* 0xad */ { NULL, NULL, 0 },
1178 /* 0xae */ { NULL, NULL, 0 },
1179 /* 0xaf */ { NULL, NULL, 0 },
1180 /* 0xb0 */ { NULL, NULL, 0 },
1181 /* 0xb1 */ { NULL, NULL, 0 },
1182 /* 0xb2 */ { NULL, NULL, 0 },
1183 /* 0xb3 */ { NULL, NULL, 0 },
1184 /* 0xb4 */ { NULL, NULL, 0 },
1185 /* 0xb5 */ { NULL, NULL, 0 },
1186 /* 0xb6 */ { NULL, NULL, 0 },
1187 /* 0xb7 */ { NULL, NULL, 0 },
1188 /* 0xb8 */ { NULL, NULL, 0 },
1189 /* 0xb9 */ { NULL, NULL, 0 },
1190 /* 0xba */ { NULL, NULL, 0 },
1191 /* 0xbb */ { NULL, NULL, 0 },
1192 /* 0xbc */ { NULL, NULL, 0 },
1193 /* 0xbd */ { NULL, NULL, 0 },
1194 /* 0xbe */ { NULL, NULL, 0 },
1195 /* 0xbf */ { NULL, NULL, 0 },
1196 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1197 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1198 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1199 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1200 /* 0xc4 */ { NULL, NULL, 0 },
1201 /* 0xc5 */ { NULL, NULL, 0 },
1202 /* 0xc6 */ { NULL, NULL, 0 },
1203 /* 0xc7 */ { NULL, NULL, 0 },
1204 /* 0xc8 */ { NULL, NULL, 0 },
1205 /* 0xc9 */ { NULL, NULL, 0 },
1206 /* 0xca */ { NULL, NULL, 0 },
1207 /* 0xcb */ { NULL, NULL, 0 },
1208 /* 0xcc */ { NULL, NULL, 0 },
1209 /* 0xcd */ { NULL, NULL, 0 },
1210 /* 0xce */ { NULL, NULL, 0 },
1211 /* 0xcf */ { NULL, NULL, 0 },
1212 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1213 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1214 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1215 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1216 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1217 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1218 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1219 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1220 /* 0xd8 */ { NULL, NULL, 0 },
1221 /* 0xd9 */ { NULL, NULL, 0 },
1222 /* 0xda */ { NULL, NULL, 0 },
1223 /* 0xdb */ { NULL, NULL, 0 },
1224 /* 0xdc */ { NULL, NULL, 0 },
1225 /* 0xdd */ { NULL, NULL, 0 },
1226 /* 0xde */ { NULL, NULL, 0 },
1227 /* 0xdf */ { NULL, NULL, 0 },
1228 /* 0xe0 */ { NULL, NULL, 0 },
1229 /* 0xe1 */ { NULL, NULL, 0 },
1230 /* 0xe2 */ { NULL, NULL, 0 },
1231 /* 0xe3 */ { NULL, NULL, 0 },
1232 /* 0xe4 */ { NULL, NULL, 0 },
1233 /* 0xe5 */ { NULL, NULL, 0 },
1234 /* 0xe6 */ { NULL, NULL, 0 },
1235 /* 0xe7 */ { NULL, NULL, 0 },
1236 /* 0xe8 */ { NULL, NULL, 0 },
1237 /* 0xe9 */ { NULL, NULL, 0 },
1238 /* 0xea */ { NULL, NULL, 0 },
1239 /* 0xeb */ { NULL, NULL, 0 },
1240 /* 0xec */ { NULL, NULL, 0 },
1241 /* 0xed */ { NULL, NULL, 0 },
1242 /* 0xee */ { NULL, NULL, 0 },
1243 /* 0xef */ { NULL, NULL, 0 },
1244 /* 0xf0 */ { NULL, NULL, 0 },
1245 /* 0xf1 */ { NULL, NULL, 0 },
1246 /* 0xf2 */ { NULL, NULL, 0 },
1247 /* 0xf3 */ { NULL, NULL, 0 },
1248 /* 0xf4 */ { NULL, NULL, 0 },
1249 /* 0xf5 */ { NULL, NULL, 0 },
1250 /* 0xf6 */ { NULL, NULL, 0 },
1251 /* 0xf7 */ { NULL, NULL, 0 },
1252 /* 0xf8 */ { NULL, NULL, 0 },
1253 /* 0xf9 */ { NULL, NULL, 0 },
1254 /* 0xfa */ { NULL, NULL, 0 },
1255 /* 0xfb */ { NULL, NULL, 0 },
1256 /* 0xfc */ { NULL, NULL, 0 },
1257 /* 0xfd */ { NULL, NULL, 0 },
1258 /* 0xfe */ { NULL, NULL, 0 },
1259 /* 0xff */ { NULL, NULL, 0 }
1263 /*******************************************************************
1264 allocate and initialize a reply packet
1265 ********************************************************************/
1267 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1268 const char *inbuf, char **outbuf, uint8_t num_words,
1269 uint32_t num_bytes)
1272 * Protect against integer wrap
1274 if ((num_bytes > 0xffffff)
1275 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1276 char *msg;
1277 if (asprintf(&msg, "num_bytes too large: %u",
1278 (unsigned)num_bytes) == -1) {
1279 msg = discard_const_p(char, "num_bytes too large");
1281 smb_panic(msg);
1284 *outbuf = talloc_array(mem_ctx, char,
1285 smb_size + num_words*2 + num_bytes);
1286 if (*outbuf == NULL) {
1287 return false;
1290 construct_reply_common(req, inbuf, *outbuf);
1291 srv_set_message(*outbuf, num_words, num_bytes, false);
1293 * Zero out the word area, the caller has to take care of the bcc area
1294 * himself
1296 if (num_words != 0) {
1297 memset(*outbuf + smb_vwv0, 0, num_words*2);
1300 return true;
1303 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1305 char *outbuf;
1306 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1307 num_bytes)) {
1308 smb_panic("could not allocate output buffer\n");
1310 req->outbuf = (uint8_t *)outbuf;
1314 /*******************************************************************
1315 Dump a packet to a file.
1316 ********************************************************************/
1318 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1320 int fd, i;
1321 char *fname = NULL;
1322 if (DEBUGLEVEL < 50) {
1323 return;
1326 if (len < 4) len = smb_len(data)+4;
1327 for (i=1;i<100;i++) {
1328 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1329 type ? "req" : "resp") == -1) {
1330 return;
1332 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1333 if (fd != -1 || errno != EEXIST) break;
1335 if (fd != -1) {
1336 ssize_t ret = write(fd, data, len);
1337 if (ret != len)
1338 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1339 close(fd);
1340 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1342 SAFE_FREE(fname);
1345 /****************************************************************************
1346 Prepare everything for calling the actual request function, and potentially
1347 call the request function via the "new" interface.
1349 Return False if the "legacy" function needs to be called, everything is
1350 prepared.
1352 Return True if we're done.
1354 I know this API sucks, but it is the one with the least code change I could
1355 find.
1356 ****************************************************************************/
1358 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1360 int flags;
1361 uint16 session_tag;
1362 connection_struct *conn = NULL;
1363 struct smbd_server_connection *sconn = req->sconn;
1364 char *raddr;
1366 errno = 0;
1368 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1369 * so subtract 4 from it. */
1370 if (!valid_smb_header(req->inbuf)
1371 || (size < (smb_size - 4))) {
1372 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1373 smb_len(req->inbuf)));
1374 exit_server_cleanly("Non-SMB packet");
1377 if (smb_messages[type].fn == NULL) {
1378 DEBUG(0,("Unknown message type %d!\n",type));
1379 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1380 reply_unknown_new(req, type);
1381 return NULL;
1384 flags = smb_messages[type].flags;
1386 /* In share mode security we must ignore the vuid. */
1387 session_tag = (lp_security() == SEC_SHARE)
1388 ? UID_FIELD_INVALID : req->vuid;
1389 conn = req->conn;
1391 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1392 (int)sys_getpid(), (unsigned long)conn));
1394 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1396 /* Ensure this value is replaced in the incoming packet. */
1397 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1400 * Ensure the correct username is in current_user_info. This is a
1401 * really ugly bugfix for problems with multiple session_setup_and_X's
1402 * being done and allowing %U and %G substitutions to work correctly.
1403 * There is a reason this code is done here, don't move it unless you
1404 * know what you're doing... :-).
1405 * JRA.
1408 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1409 user_struct *vuser = NULL;
1411 sconn->smb1.sessions.last_session_tag = session_tag;
1412 if(session_tag != UID_FIELD_INVALID) {
1413 vuser = get_valid_user_struct(sconn, session_tag);
1414 if (vuser) {
1415 set_current_user_info(
1416 vuser->session_info->unix_info->sanitized_username,
1417 vuser->session_info->unix_info->unix_name,
1418 vuser->session_info->info->domain_name);
1423 /* Does this call need to be run as the connected user? */
1424 if (flags & AS_USER) {
1426 /* Does this call need a valid tree connection? */
1427 if (!conn) {
1429 * Amazingly, the error code depends on the command
1430 * (from Samba4).
1432 if (type == SMBntcreateX) {
1433 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1434 } else {
1435 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1437 return NULL;
1440 if (!change_to_user(conn,session_tag)) {
1441 DEBUG(0, ("Error: Could not change to user. Removing "
1442 "deferred open, mid=%llu.\n",
1443 (unsigned long long)req->mid));
1444 reply_force_doserror(req, ERRSRV, ERRbaduid);
1445 return conn;
1448 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1450 /* Does it need write permission? */
1451 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1452 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1453 return conn;
1456 /* IPC services are limited */
1457 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1458 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1459 return conn;
1461 } else {
1462 /* This call needs to be run as root */
1463 change_to_root_user();
1466 /* load service specific parameters */
1467 if (conn) {
1468 if (req->encrypted) {
1469 conn->encrypted_tid = true;
1470 /* encrypted required from now on. */
1471 conn->encrypt_level = Required;
1472 } else if (ENCRYPTION_REQUIRED(conn)) {
1473 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1474 exit_server_cleanly("encryption required "
1475 "on connection");
1476 return conn;
1480 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1481 (flags & (AS_USER|DO_CHDIR)
1482 ?True:False))) {
1483 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1484 return conn;
1486 conn->num_smb_operations++;
1489 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1490 talloc_tos());
1491 if (raddr == NULL) {
1492 reply_nterror(req, NT_STATUS_NO_MEMORY);
1493 return conn;
1496 /* does this protocol need to be run as guest? */
1497 if ((flags & AS_GUEST)
1498 && (!change_to_guest() ||
1499 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1500 sconn->remote_hostname,
1501 raddr))) {
1502 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1503 return conn;
1506 smb_messages[type].fn(req);
1507 return req->conn;
1510 /****************************************************************************
1511 Construct a reply to the incoming packet.
1512 ****************************************************************************/
1514 static void construct_reply(struct smbd_server_connection *sconn,
1515 char *inbuf, int size, size_t unread_bytes,
1516 uint32_t seqnum, bool encrypted,
1517 struct smb_perfcount_data *deferred_pcd)
1519 connection_struct *conn;
1520 struct smb_request *req;
1522 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1523 smb_panic("could not allocate smb_request");
1526 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1527 encrypted, seqnum)) {
1528 exit_server_cleanly("Invalid SMB request");
1531 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1533 /* we popped this message off the queue - keep original perf data */
1534 if (deferred_pcd)
1535 req->pcd = *deferred_pcd;
1536 else {
1537 SMB_PERFCOUNT_START(&req->pcd);
1538 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1539 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1542 conn = switch_message(req->cmd, req, size);
1544 if (req->unread_bytes) {
1545 /* writeX failed. drain socket. */
1546 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1547 req->unread_bytes) {
1548 smb_panic("failed to drain pending bytes");
1550 req->unread_bytes = 0;
1553 if (req->done) {
1554 TALLOC_FREE(req);
1555 return;
1558 if (req->outbuf == NULL) {
1559 return;
1562 if (CVAL(req->outbuf,0) == 0) {
1563 show_msg((char *)req->outbuf);
1566 if (!srv_send_smb(req->sconn,
1567 (char *)req->outbuf,
1568 true, req->seqnum+1,
1569 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1570 &req->pcd)) {
1571 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1574 TALLOC_FREE(req);
1576 return;
1579 /****************************************************************************
1580 Process an smb from the client
1581 ****************************************************************************/
1582 static void process_smb(struct smbd_server_connection *sconn,
1583 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1584 uint32_t seqnum, bool encrypted,
1585 struct smb_perfcount_data *deferred_pcd)
1587 int msg_type = CVAL(inbuf,0);
1589 DO_PROFILE_INC(smb_count);
1591 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1592 smb_len(inbuf) ) );
1593 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1594 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1596 if (msg_type != NBSSmessage) {
1598 * NetBIOS session request, keepalive, etc.
1600 reply_special(sconn, (char *)inbuf, nread);
1601 goto done;
1604 if (sconn->using_smb2) {
1605 /* At this point we're not really using smb2,
1606 * we make the decision here.. */
1607 if (smbd_is_smb2_header(inbuf, nread)) {
1608 smbd_smb2_first_negprot(sconn, inbuf, nread);
1609 return;
1610 } else if (nread >= smb_size && valid_smb_header(inbuf)
1611 && CVAL(inbuf, smb_com) != 0x72) {
1612 /* This is a non-negprot SMB1 packet.
1613 Disable SMB2 from now on. */
1614 sconn->using_smb2 = false;
1618 show_msg((char *)inbuf);
1620 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1621 encrypted, deferred_pcd);
1622 sconn->trans_num++;
1624 done:
1625 sconn->num_requests++;
1627 /* The timeout_processing function isn't run nearly
1628 often enough to implement 'max log size' without
1629 overrunning the size of the file by many megabytes.
1630 This is especially true if we are running at debug
1631 level 10. Checking every 50 SMBs is a nice
1632 tradeoff of performance vs log file size overrun. */
1634 if ((sconn->num_requests % 50) == 0 &&
1635 need_to_check_log_size()) {
1636 change_to_root_user();
1637 check_log_size();
1641 /****************************************************************************
1642 Return a string containing the function name of a SMB command.
1643 ****************************************************************************/
1645 const char *smb_fn_name(int type)
1647 const char *unknown_name = "SMBunknown";
1649 if (smb_messages[type].name == NULL)
1650 return(unknown_name);
1652 return(smb_messages[type].name);
1655 /****************************************************************************
1656 Helper functions for contruct_reply.
1657 ****************************************************************************/
1659 void add_to_common_flags2(uint32 v)
1661 common_flags2 |= v;
1664 void remove_from_common_flags2(uint32 v)
1666 common_flags2 &= ~v;
1669 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1670 char *outbuf)
1672 srv_set_message(outbuf,0,0,false);
1674 SCVAL(outbuf, smb_com, req->cmd);
1675 SIVAL(outbuf,smb_rcls,0);
1676 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1677 SSVAL(outbuf,smb_flg2,
1678 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1679 common_flags2);
1680 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1682 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1683 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1684 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1685 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1688 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1690 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1694 * How many bytes have we already accumulated up to the current wct field
1695 * offset?
1698 size_t req_wct_ofs(struct smb_request *req)
1700 size_t buf_size;
1702 if (req->chain_outbuf == NULL) {
1703 return smb_wct - 4;
1705 buf_size = talloc_get_size(req->chain_outbuf);
1706 if ((buf_size % 4) != 0) {
1707 buf_size += (4 - (buf_size % 4));
1709 return buf_size - 4;
1713 * Hack around reply_nterror & friends not being aware of chained requests,
1714 * generating illegal (i.e. wct==0) chain replies.
1717 static void fixup_chain_error_packet(struct smb_request *req)
1719 uint8_t *outbuf = req->outbuf;
1720 req->outbuf = NULL;
1721 reply_outbuf(req, 2, 0);
1722 memcpy(req->outbuf, outbuf, smb_wct);
1723 TALLOC_FREE(outbuf);
1724 SCVAL(req->outbuf, smb_vwv0, 0xff);
1728 * @brief Find the smb_cmd offset of the last command pushed
1729 * @param[in] buf The buffer we're building up
1730 * @retval Where can we put our next andx cmd?
1732 * While chaining requests, the "next" request we're looking at needs to put
1733 * its SMB_Command before the data the previous request already built up added
1734 * to the chain. Find the offset to the place where we have to put our cmd.
1737 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1739 uint8_t cmd;
1740 size_t ofs;
1742 cmd = CVAL(buf, smb_com);
1744 SMB_ASSERT(is_andx_req(cmd));
1746 ofs = smb_vwv0;
1748 while (CVAL(buf, ofs) != 0xff) {
1750 if (!is_andx_req(CVAL(buf, ofs))) {
1751 return false;
1755 * ofs is from start of smb header, so add the 4 length
1756 * bytes. The next cmd is right after the wct field.
1758 ofs = SVAL(buf, ofs+2) + 4 + 1;
1760 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1763 *pofs = ofs;
1764 return true;
1768 * @brief Do the smb chaining at a buffer level
1769 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1770 * @param[in] smb_command The command that we want to issue
1771 * @param[in] wct How many words?
1772 * @param[in] vwv The words, already in network order
1773 * @param[in] bytes_alignment How shall we align "bytes"?
1774 * @param[in] num_bytes How many bytes?
1775 * @param[in] bytes The data the request ships
1777 * smb_splice_chain() adds the vwv and bytes to the request already present in
1778 * *poutbuf.
1781 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1782 uint8_t wct, const uint16_t *vwv,
1783 size_t bytes_alignment,
1784 uint32_t num_bytes, const uint8_t *bytes)
1786 uint8_t *outbuf;
1787 size_t old_size, new_size;
1788 size_t ofs;
1789 size_t chain_padding = 0;
1790 size_t bytes_padding = 0;
1791 bool first_request;
1793 old_size = talloc_get_size(*poutbuf);
1796 * old_size == smb_wct means we're pushing the first request in for
1797 * libsmb/
1800 first_request = (old_size == smb_wct);
1802 if (!first_request && ((old_size % 4) != 0)) {
1804 * Align the wct field of subsequent requests to a 4-byte
1805 * boundary
1807 chain_padding = 4 - (old_size % 4);
1811 * After the old request comes the new wct field (1 byte), the vwv's
1812 * and the num_bytes field. After at we might need to align the bytes
1813 * given to us to "bytes_alignment", increasing the num_bytes value.
1816 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1818 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1819 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1822 new_size += bytes_padding + num_bytes;
1824 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1825 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1826 (unsigned)new_size));
1827 return false;
1830 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1831 if (outbuf == NULL) {
1832 DEBUG(0, ("talloc failed\n"));
1833 return false;
1835 *poutbuf = outbuf;
1837 if (first_request) {
1838 SCVAL(outbuf, smb_com, smb_command);
1839 } else {
1840 size_t andx_cmd_ofs;
1842 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1843 DEBUG(1, ("invalid command chain\n"));
1844 *poutbuf = talloc_realloc(
1845 NULL, *poutbuf, uint8_t, old_size);
1846 return false;
1849 if (chain_padding != 0) {
1850 memset(outbuf + old_size, 0, chain_padding);
1851 old_size += chain_padding;
1854 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1855 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1858 ofs = old_size;
1861 * Push the chained request:
1863 * wct field
1866 SCVAL(outbuf, ofs, wct);
1867 ofs += 1;
1870 * vwv array
1873 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1874 ofs += sizeof(uint16_t) * wct;
1877 * bcc (byte count)
1880 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1881 ofs += sizeof(uint16_t);
1884 * padding
1887 if (bytes_padding != 0) {
1888 memset(outbuf + ofs, 0, bytes_padding);
1889 ofs += bytes_padding;
1893 * The bytes field
1896 memcpy(outbuf + ofs, bytes, num_bytes);
1898 return true;
1901 /****************************************************************************
1902 Construct a chained reply and add it to the already made reply
1903 ****************************************************************************/
1905 void chain_reply(struct smb_request *req)
1907 size_t smblen = smb_len(req->inbuf);
1908 size_t already_used, length_needed;
1909 uint8_t chain_cmd;
1910 uint32_t chain_offset; /* uint32_t to avoid overflow */
1912 uint8_t wct;
1913 const uint16_t *vwv;
1914 uint16_t buflen;
1915 const uint8_t *buf;
1917 if (IVAL(req->outbuf, smb_rcls) != 0) {
1918 fixup_chain_error_packet(req);
1922 * Any of the AndX requests and replies have at least a wct of
1923 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1924 * beginning of the SMB header to the next wct field.
1926 * None of the AndX requests put anything valuable in vwv[0] and [1],
1927 * so we can overwrite it here to form the chain.
1930 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1931 if (req->chain_outbuf == NULL) {
1932 req->chain_outbuf = talloc_realloc(
1933 req, req->outbuf, uint8_t,
1934 smb_len(req->outbuf) + 4);
1935 if (req->chain_outbuf == NULL) {
1936 smb_panic("talloc failed");
1939 req->outbuf = NULL;
1940 goto error;
1944 * Here we assume that this is the end of the chain. For that we need
1945 * to set "next command" to 0xff and the offset to 0. If we later find
1946 * more commands in the chain, this will be overwritten again.
1949 SCVAL(req->outbuf, smb_vwv0, 0xff);
1950 SCVAL(req->outbuf, smb_vwv0+1, 0);
1951 SSVAL(req->outbuf, smb_vwv1, 0);
1953 if (req->chain_outbuf == NULL) {
1955 * In req->chain_outbuf we collect all the replies. Start the
1956 * chain by copying in the first reply.
1958 * We do the realloc because later on we depend on
1959 * talloc_get_size to determine the length of
1960 * chain_outbuf. The reply_xxx routines might have
1961 * over-allocated (reply_pipe_read_and_X used to be such an
1962 * example).
1964 req->chain_outbuf = talloc_realloc(
1965 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1966 if (req->chain_outbuf == NULL) {
1967 smb_panic("talloc failed");
1969 req->outbuf = NULL;
1970 } else {
1972 * Update smb headers where subsequent chained commands
1973 * may have updated them.
1975 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1976 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1978 if (!smb_splice_chain(&req->chain_outbuf,
1979 CVAL(req->outbuf, smb_com),
1980 CVAL(req->outbuf, smb_wct),
1981 (uint16_t *)(req->outbuf + smb_vwv),
1982 0, smb_buflen(req->outbuf),
1983 (uint8_t *)smb_buf(req->outbuf))) {
1984 goto error;
1986 TALLOC_FREE(req->outbuf);
1990 * We use the old request's vwv field to grab the next chained command
1991 * and offset into the chained fields.
1994 chain_cmd = CVAL(req->vwv+0, 0);
1995 chain_offset = SVAL(req->vwv+1, 0);
1997 if (chain_cmd == 0xff) {
1999 * End of chain, no more requests from the client. So ship the
2000 * replies.
2002 smb_setlen((char *)(req->chain_outbuf),
2003 talloc_get_size(req->chain_outbuf) - 4);
2005 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2006 true, req->seqnum+1,
2007 IS_CONN_ENCRYPTED(req->conn)
2008 ||req->encrypted,
2009 &req->pcd)) {
2010 exit_server_cleanly("chain_reply: srv_send_smb "
2011 "failed.");
2013 TALLOC_FREE(req->chain_outbuf);
2014 req->done = true;
2015 return;
2018 /* add a new perfcounter for this element of chain */
2019 SMB_PERFCOUNT_ADD(&req->pcd);
2020 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2021 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2024 * Check if the client tries to fool us. The request so far uses the
2025 * space to the end of the byte buffer in the request just
2026 * processed. The chain_offset can't point into that area. If that was
2027 * the case, we could end up with an endless processing of the chain,
2028 * we would always handle the same request.
2031 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2032 if (chain_offset < already_used) {
2033 goto error;
2037 * Next check: Make sure the chain offset does not point beyond the
2038 * overall smb request length.
2041 length_needed = chain_offset+1; /* wct */
2042 if (length_needed > smblen) {
2043 goto error;
2047 * Now comes the pointer magic. Goal here is to set up req->vwv and
2048 * req->buf correctly again to be able to call the subsequent
2049 * switch_message(). The chain offset (the former vwv[1]) points at
2050 * the new wct field.
2053 wct = CVAL(smb_base(req->inbuf), chain_offset);
2056 * Next consistency check: Make the new vwv array fits in the overall
2057 * smb request.
2060 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2061 if (length_needed > smblen) {
2062 goto error;
2064 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2067 * Now grab the new byte buffer....
2070 buflen = SVAL(vwv+wct, 0);
2073 * .. and check that it fits.
2076 length_needed += buflen;
2077 if (length_needed > smblen) {
2078 goto error;
2080 buf = (const uint8_t *)(vwv+wct+1);
2082 req->cmd = chain_cmd;
2083 req->wct = wct;
2084 req->vwv = discard_const_p(uint16_t, vwv);
2085 req->buflen = buflen;
2086 req->buf = buf;
2088 switch_message(chain_cmd, req, smblen);
2090 if (req->outbuf == NULL) {
2092 * This happens if the chained command has suspended itself or
2093 * if it has called srv_send_smb() itself.
2095 return;
2099 * We end up here if the chained command was not itself chained or
2100 * suspended, but for example a close() command. We now need to splice
2101 * the chained commands' outbuf into the already built up chain_outbuf
2102 * and ship the result.
2104 goto done;
2106 error:
2108 * We end up here if there's any error in the chain syntax. Report a
2109 * DOS error, just like Windows does.
2111 reply_force_doserror(req, ERRSRV, ERRerror);
2112 fixup_chain_error_packet(req);
2114 done:
2116 * This scary statement intends to set the
2117 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2118 * to the value req->outbuf carries
2120 SSVAL(req->chain_outbuf, smb_flg2,
2121 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2122 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2125 * Transfer the error codes from the subrequest to the main one
2127 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2128 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2130 if (!smb_splice_chain(&req->chain_outbuf,
2131 CVAL(req->outbuf, smb_com),
2132 CVAL(req->outbuf, smb_wct),
2133 (uint16_t *)(req->outbuf + smb_vwv),
2134 0, smb_buflen(req->outbuf),
2135 (uint8_t *)smb_buf(req->outbuf))) {
2136 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2138 TALLOC_FREE(req->outbuf);
2140 smb_setlen((char *)(req->chain_outbuf),
2141 talloc_get_size(req->chain_outbuf) - 4);
2143 show_msg((char *)(req->chain_outbuf));
2145 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2146 true, req->seqnum+1,
2147 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2148 &req->pcd)) {
2149 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2151 TALLOC_FREE(req->chain_outbuf);
2152 req->done = true;
2155 /****************************************************************************
2156 Check if services need reloading.
2157 ****************************************************************************/
2159 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2162 if (last_smb_conf_reload_time == 0) {
2163 last_smb_conf_reload_time = t;
2166 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2167 reload_services(sconn->msg_ctx, sconn->sock, True);
2168 last_smb_conf_reload_time = t;
2172 static bool fd_is_readable(int fd)
2174 int ret, revents;
2176 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2178 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2182 static void smbd_server_connection_write_handler(
2183 struct smbd_server_connection *sconn)
2185 /* TODO: make write nonblocking */
2188 static void smbd_server_connection_read_handler(
2189 struct smbd_server_connection *sconn, int fd)
2191 uint8_t *inbuf = NULL;
2192 size_t inbuf_len = 0;
2193 size_t unread_bytes = 0;
2194 bool encrypted = false;
2195 TALLOC_CTX *mem_ctx = talloc_tos();
2196 NTSTATUS status;
2197 uint32_t seqnum;
2199 bool from_client = (sconn->sock == fd);
2201 if (from_client) {
2202 smbd_lock_socket(sconn);
2204 if (lp_async_smb_echo_handler()) {
2206 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2208 * This is the super-ugly hack to
2209 * prefer the packets forwarded by the
2210 * echo handler over the ones by the
2211 * client directly
2213 fd = sconn->smb1.echo_handler.trusted_fd;
2214 } else if (!fd_is_readable(fd)) {
2215 DEBUG(10,("the echo listener was faster\n"));
2216 smbd_unlock_socket(sconn);
2217 return;
2221 /* TODO: make this completely nonblocking */
2222 status = receive_smb_talloc(mem_ctx, sconn, fd,
2223 (char **)(void *)&inbuf,
2224 0, /* timeout */
2225 &unread_bytes,
2226 &encrypted,
2227 &inbuf_len, &seqnum,
2228 false /* trusted channel */);
2229 smbd_unlock_socket(sconn);
2230 } else {
2231 /* TODO: make this completely nonblocking */
2232 status = receive_smb_talloc(mem_ctx, sconn, fd,
2233 (char **)(void *)&inbuf,
2234 0, /* timeout */
2235 &unread_bytes,
2236 &encrypted,
2237 &inbuf_len, &seqnum,
2238 true /* trusted channel */);
2241 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2242 goto process;
2244 if (NT_STATUS_IS_ERR(status)) {
2245 exit_server_cleanly("failed to receive smb request");
2247 if (!NT_STATUS_IS_OK(status)) {
2248 return;
2251 process:
2252 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2253 seqnum, encrypted, NULL);
2256 static void smbd_server_connection_handler(struct event_context *ev,
2257 struct fd_event *fde,
2258 uint16_t flags,
2259 void *private_data)
2261 struct smbd_server_connection *conn = talloc_get_type(private_data,
2262 struct smbd_server_connection);
2264 if (flags & EVENT_FD_WRITE) {
2265 smbd_server_connection_write_handler(conn);
2266 return;
2268 if (flags & EVENT_FD_READ) {
2269 smbd_server_connection_read_handler(conn, conn->sock);
2270 return;
2274 static void smbd_server_echo_handler(struct event_context *ev,
2275 struct fd_event *fde,
2276 uint16_t flags,
2277 void *private_data)
2279 struct smbd_server_connection *conn = talloc_get_type(private_data,
2280 struct smbd_server_connection);
2282 if (flags & EVENT_FD_WRITE) {
2283 smbd_server_connection_write_handler(conn);
2284 return;
2286 if (flags & EVENT_FD_READ) {
2287 smbd_server_connection_read_handler(
2288 conn, conn->smb1.echo_handler.trusted_fd);
2289 return;
2293 #ifdef CLUSTER_SUPPORT
2294 /****************************************************************************
2295 received when we should release a specific IP
2296 ****************************************************************************/
2297 static void release_ip(const char *ip, void *priv)
2299 const char *addr = (const char *)priv;
2300 const char *p = addr;
2302 if (strncmp("::ffff:", addr, 7) == 0) {
2303 p = addr + 7;
2306 DEBUG(10, ("Got release IP message for %s, "
2307 "our address is %s\n", ip, p));
2309 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2310 /* we can't afford to do a clean exit - that involves
2311 database writes, which would potentially mean we
2312 are still running after the failover has finished -
2313 we have to get rid of this process ID straight
2314 away */
2315 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2316 ip));
2317 /* note we must exit with non-zero status so the unclean handler gets
2318 called in the parent, so that the brl database is tickled */
2319 _exit(1);
2323 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2324 struct sockaddr_storage *client)
2326 socklen_t length;
2327 length = sizeof(*server);
2328 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2329 return -1;
2331 length = sizeof(*client);
2332 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2333 return -1;
2335 return 0;
2337 #endif
2340 * Send keepalive packets to our client
2342 static bool keepalive_fn(const struct timeval *now, void *private_data)
2344 struct smbd_server_connection *sconn = smbd_server_conn;
2345 bool ret;
2347 if (sconn->using_smb2) {
2348 /* Don't do keepalives on an SMB2 connection. */
2349 return false;
2352 smbd_lock_socket(smbd_server_conn);
2353 ret = send_keepalive(sconn->sock);
2354 smbd_unlock_socket(smbd_server_conn);
2356 if (!ret) {
2357 char addr[INET6_ADDRSTRLEN];
2359 * Try and give an error message saying what
2360 * client failed.
2362 DEBUG(0, ("send_keepalive failed for client %s. "
2363 "Error %s - exiting\n",
2364 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2365 strerror(errno)));
2366 return False;
2368 return True;
2372 * Do the recurring check if we're idle
2374 static bool deadtime_fn(const struct timeval *now, void *private_data)
2376 struct smbd_server_connection *sconn =
2377 (struct smbd_server_connection *)private_data;
2379 if ((conn_num_open(sconn) == 0)
2380 || (conn_idle_all(sconn, now->tv_sec))) {
2381 DEBUG( 2, ( "Closing idle connection\n" ) );
2382 messaging_send(sconn->msg_ctx,
2383 messaging_server_id(sconn->msg_ctx),
2384 MSG_SHUTDOWN, &data_blob_null);
2385 return False;
2388 return True;
2392 * Do the recurring log file and smb.conf reload checks.
2395 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2397 struct smbd_server_connection *sconn = talloc_get_type_abort(
2398 private_data, struct smbd_server_connection);
2400 DEBUG(5, ("housekeeping\n"));
2402 change_to_root_user();
2404 /* update printer queue caches if necessary */
2405 update_monitored_printq_cache(sconn->msg_ctx);
2407 /* check if we need to reload services */
2408 check_reload(sconn, time_mono(NULL));
2410 /* Change machine password if neccessary. */
2411 attempt_machine_password_change();
2414 * Force a log file check.
2416 force_check_log_size();
2417 check_log_size();
2418 return true;
2421 static int create_unlink_tmp(const char *dir)
2423 char *fname;
2424 int fd;
2426 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2427 if (fname == NULL) {
2428 errno = ENOMEM;
2429 return -1;
2431 fd = mkstemp(fname);
2432 if (fd == -1) {
2433 TALLOC_FREE(fname);
2434 return -1;
2436 if (unlink(fname) == -1) {
2437 int sys_errno = errno;
2438 close(fd);
2439 TALLOC_FREE(fname);
2440 errno = sys_errno;
2441 return -1;
2443 TALLOC_FREE(fname);
2444 return fd;
2448 * Read an smb packet in the echo handler child, giving the parent
2449 * smbd one second to react once the socket becomes readable.
2452 struct smbd_echo_read_state {
2453 struct tevent_context *ev;
2454 struct smbd_server_connection *sconn;
2456 char *buf;
2457 size_t buflen;
2458 uint32_t seqnum;
2461 static void smbd_echo_read_readable(struct tevent_req *subreq);
2462 static void smbd_echo_read_waited(struct tevent_req *subreq);
2464 static struct tevent_req *smbd_echo_read_send(
2465 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2466 struct smbd_server_connection *sconn)
2468 struct tevent_req *req, *subreq;
2469 struct smbd_echo_read_state *state;
2471 req = tevent_req_create(mem_ctx, &state,
2472 struct smbd_echo_read_state);
2473 if (req == NULL) {
2474 return NULL;
2476 state->ev = ev;
2477 state->sconn = sconn;
2479 subreq = wait_for_read_send(state, ev, sconn->sock);
2480 if (tevent_req_nomem(subreq, req)) {
2481 return tevent_req_post(req, ev);
2483 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2484 return req;
2487 static void smbd_echo_read_readable(struct tevent_req *subreq)
2489 struct tevent_req *req = tevent_req_callback_data(
2490 subreq, struct tevent_req);
2491 struct smbd_echo_read_state *state = tevent_req_data(
2492 req, struct smbd_echo_read_state);
2493 bool ok;
2494 int err;
2496 ok = wait_for_read_recv(subreq, &err);
2497 TALLOC_FREE(subreq);
2498 if (!ok) {
2499 tevent_req_nterror(req, map_nt_error_from_unix(err));
2500 return;
2504 * Give the parent smbd one second to step in
2507 subreq = tevent_wakeup_send(
2508 state, state->ev, timeval_current_ofs(1, 0));
2509 if (tevent_req_nomem(subreq, req)) {
2510 return;
2512 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2515 static void smbd_echo_read_waited(struct tevent_req *subreq)
2517 struct tevent_req *req = tevent_req_callback_data(
2518 subreq, struct tevent_req);
2519 struct smbd_echo_read_state *state = tevent_req_data(
2520 req, struct smbd_echo_read_state);
2521 struct smbd_server_connection *sconn = state->sconn;
2522 bool ok;
2523 NTSTATUS status;
2524 size_t unread = 0;
2525 bool encrypted;
2527 ok = tevent_wakeup_recv(subreq);
2528 TALLOC_FREE(subreq);
2529 if (!ok) {
2530 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2531 return;
2534 ok = smbd_lock_socket_internal(sconn);
2535 if (!ok) {
2536 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2537 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2538 return;
2541 if (!fd_is_readable(sconn->sock)) {
2542 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2543 (int)sys_getpid()));
2545 ok = smbd_unlock_socket_internal(sconn);
2546 if (!ok) {
2547 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2548 DEBUG(1, ("%s: failed to unlock socket\n",
2549 __location__));
2550 return;
2553 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2554 if (tevent_req_nomem(subreq, req)) {
2555 return;
2557 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2558 return;
2561 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2562 0 /* timeout */,
2563 &unread,
2564 &encrypted,
2565 &state->buflen,
2566 &state->seqnum,
2567 false /* trusted_channel*/);
2569 if (tevent_req_nterror(req, status)) {
2570 tevent_req_nterror(req, status);
2571 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2572 (int)sys_getpid(), nt_errstr(status)));
2573 return;
2576 ok = smbd_unlock_socket_internal(sconn);
2577 if (!ok) {
2578 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2579 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2580 return;
2582 tevent_req_done(req);
2585 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2586 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2588 struct smbd_echo_read_state *state = tevent_req_data(
2589 req, struct smbd_echo_read_state);
2590 NTSTATUS status;
2592 if (tevent_req_is_nterror(req, &status)) {
2593 return status;
2595 *pbuf = talloc_move(mem_ctx, &state->buf);
2596 *pbuflen = state->buflen;
2597 *pseqnum = state->seqnum;
2598 return NT_STATUS_OK;
2601 struct smbd_echo_state {
2602 struct tevent_context *ev;
2603 struct iovec *pending;
2604 struct smbd_server_connection *sconn;
2605 int parent_pipe;
2607 struct tevent_fd *parent_fde;
2609 struct tevent_req *write_req;
2612 static void smbd_echo_writer_done(struct tevent_req *req);
2614 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2616 int num_pending;
2618 if (state->write_req != NULL) {
2619 return;
2622 num_pending = talloc_array_length(state->pending);
2623 if (num_pending == 0) {
2624 return;
2627 state->write_req = writev_send(state, state->ev, NULL,
2628 state->parent_pipe, false,
2629 state->pending, num_pending);
2630 if (state->write_req == NULL) {
2631 DEBUG(1, ("writev_send failed\n"));
2632 exit(1);
2635 talloc_steal(state->write_req, state->pending);
2636 state->pending = NULL;
2638 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2639 state);
2642 static void smbd_echo_writer_done(struct tevent_req *req)
2644 struct smbd_echo_state *state = tevent_req_callback_data(
2645 req, struct smbd_echo_state);
2646 ssize_t written;
2647 int err;
2649 written = writev_recv(req, &err);
2650 TALLOC_FREE(req);
2651 state->write_req = NULL;
2652 if (written == -1) {
2653 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2654 exit(1);
2656 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2657 smbd_echo_activate_writer(state);
2660 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2661 uint32_t seqnum)
2663 struct smb_request req;
2664 uint16_t num_replies;
2665 size_t out_len;
2666 char *outbuf;
2667 bool ok;
2669 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2670 DEBUG(10, ("Got netbios keepalive\n"));
2672 * Just swallow it
2674 return true;
2677 if (inbuf_len < smb_size) {
2678 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2679 return false;
2681 if (!valid_smb_header(inbuf)) {
2682 DEBUG(10, ("Got invalid SMB header\n"));
2683 return false;
2686 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2687 seqnum)) {
2688 return false;
2690 req.inbuf = inbuf;
2692 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2693 smb_messages[req.cmd].name
2694 ? smb_messages[req.cmd].name : "unknown"));
2696 if (req.cmd != SMBecho) {
2697 return false;
2699 if (req.wct < 1) {
2700 return false;
2703 num_replies = SVAL(req.vwv+0, 0);
2704 if (num_replies != 1) {
2705 /* Not a Windows "Hey, you're still there?" request */
2706 return false;
2709 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2710 1, req.buflen)) {
2711 DEBUG(10, ("create_outbuf failed\n"));
2712 return false;
2714 req.outbuf = (uint8_t *)outbuf;
2716 SSVAL(req.outbuf, smb_vwv0, num_replies);
2718 if (req.buflen > 0) {
2719 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2722 out_len = smb_len(req.outbuf) + 4;
2724 ok = srv_send_smb(req.sconn,
2725 (char *)outbuf,
2726 true, seqnum+1,
2727 false, &req.pcd);
2728 TALLOC_FREE(outbuf);
2729 if (!ok) {
2730 exit(1);
2733 return true;
2736 static void smbd_echo_exit(struct tevent_context *ev,
2737 struct tevent_fd *fde, uint16_t flags,
2738 void *private_data)
2740 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2741 exit(0);
2744 static void smbd_echo_got_packet(struct tevent_req *req);
2746 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2747 int parent_pipe)
2749 struct smbd_echo_state *state;
2750 struct tevent_req *read_req;
2752 state = talloc_zero(sconn, struct smbd_echo_state);
2753 if (state == NULL) {
2754 DEBUG(1, ("talloc failed\n"));
2755 return;
2757 state->sconn = sconn;
2758 state->parent_pipe = parent_pipe;
2759 state->ev = s3_tevent_context_init(state);
2760 if (state->ev == NULL) {
2761 DEBUG(1, ("tevent_context_init failed\n"));
2762 TALLOC_FREE(state);
2763 return;
2765 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2766 TEVENT_FD_READ, smbd_echo_exit,
2767 state);
2768 if (state->parent_fde == NULL) {
2769 DEBUG(1, ("tevent_add_fd failed\n"));
2770 TALLOC_FREE(state);
2771 return;
2774 read_req = smbd_echo_read_send(state, state->ev, sconn);
2775 if (read_req == NULL) {
2776 DEBUG(1, ("smbd_echo_read_send failed\n"));
2777 TALLOC_FREE(state);
2778 return;
2780 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2782 while (true) {
2783 if (tevent_loop_once(state->ev) == -1) {
2784 DEBUG(1, ("tevent_loop_once failed: %s\n",
2785 strerror(errno)));
2786 break;
2789 TALLOC_FREE(state);
2792 static void smbd_echo_got_packet(struct tevent_req *req)
2794 struct smbd_echo_state *state = tevent_req_callback_data(
2795 req, struct smbd_echo_state);
2796 NTSTATUS status;
2797 char *buf = NULL;
2798 size_t buflen = 0;
2799 uint32_t seqnum = 0;
2800 bool reply;
2802 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2803 TALLOC_FREE(req);
2804 if (!NT_STATUS_IS_OK(status)) {
2805 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2806 nt_errstr(status)));
2807 exit(1);
2810 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2811 if (!reply) {
2812 size_t num_pending;
2813 struct iovec *tmp;
2814 struct iovec *iov;
2816 num_pending = talloc_array_length(state->pending);
2817 tmp = talloc_realloc(state, state->pending, struct iovec,
2818 num_pending+1);
2819 if (tmp == NULL) {
2820 DEBUG(1, ("talloc_realloc failed\n"));
2821 exit(1);
2823 state->pending = tmp;
2825 if (buflen >= smb_size) {
2827 * place the seqnum in the packet so that the main process
2828 * can reply with signing
2830 SIVAL(buf, smb_ss_field, seqnum);
2831 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2834 iov = &state->pending[num_pending];
2835 iov->iov_base = buf;
2836 iov->iov_len = buflen;
2838 DEBUG(10,("echo_handler[%d]: forward to main\n",
2839 (int)sys_getpid()));
2840 smbd_echo_activate_writer(state);
2843 req = smbd_echo_read_send(state, state->ev, state->sconn);
2844 if (req == NULL) {
2845 DEBUG(1, ("smbd_echo_read_send failed\n"));
2846 exit(1);
2848 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2853 * Handle SMBecho requests in a forked child process
2855 bool fork_echo_handler(struct smbd_server_connection *sconn)
2857 int listener_pipe[2];
2858 int res;
2859 pid_t child;
2861 res = pipe(listener_pipe);
2862 if (res == -1) {
2863 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2864 return false;
2866 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2867 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2868 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2869 goto fail;
2872 child = sys_fork();
2873 if (child == 0) {
2874 NTSTATUS status;
2876 close(listener_pipe[0]);
2877 set_blocking(listener_pipe[1], false);
2879 status = reinit_after_fork(sconn->msg_ctx,
2880 server_event_context(),
2881 procid_self(), false);
2882 if (!NT_STATUS_IS_OK(status)) {
2883 DEBUG(1, ("reinit_after_fork failed: %s\n",
2884 nt_errstr(status)));
2885 exit(1);
2887 smbd_echo_loop(sconn, listener_pipe[1]);
2888 exit(0);
2890 close(listener_pipe[1]);
2891 listener_pipe[1] = -1;
2892 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2894 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2897 * Without smb signing this is the same as the normal smbd
2898 * listener. This needs to change once signing comes in.
2900 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2901 sconn,
2902 sconn->smb1.echo_handler.trusted_fd,
2903 EVENT_FD_READ,
2904 smbd_server_echo_handler,
2905 sconn);
2906 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2907 DEBUG(1, ("event_add_fd failed\n"));
2908 goto fail;
2911 return true;
2913 fail:
2914 if (listener_pipe[0] != -1) {
2915 close(listener_pipe[0]);
2917 if (listener_pipe[1] != -1) {
2918 close(listener_pipe[1]);
2920 sconn->smb1.echo_handler.trusted_fd = -1;
2921 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2922 close(sconn->smb1.echo_handler.socket_lock_fd);
2924 sconn->smb1.echo_handler.trusted_fd = -1;
2925 sconn->smb1.echo_handler.socket_lock_fd = -1;
2926 return false;
2929 #if CLUSTER_SUPPORT
2931 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2932 struct sockaddr_storage *srv,
2933 struct sockaddr_storage *clnt)
2935 struct ctdbd_connection *cconn;
2936 char tmp_addr[INET6_ADDRSTRLEN];
2937 char *addr;
2939 cconn = messaging_ctdbd_connection();
2940 if (cconn == NULL) {
2941 return NT_STATUS_NO_MEMORY;
2944 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2945 addr = talloc_strdup(cconn, tmp_addr);
2946 if (addr == NULL) {
2947 return NT_STATUS_NO_MEMORY;
2949 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2952 #endif
2954 /****************************************************************************
2955 Process commands from the client
2956 ****************************************************************************/
2958 void smbd_process(struct smbd_server_connection *sconn)
2960 TALLOC_CTX *frame = talloc_stackframe();
2961 struct sockaddr_storage ss;
2962 struct sockaddr *sa = NULL;
2963 socklen_t sa_socklen;
2964 struct tsocket_address *local_address = NULL;
2965 struct tsocket_address *remote_address = NULL;
2966 const char *remaddr = NULL;
2967 char *rhost;
2968 int ret;
2970 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2972 * We're not making the decision here,
2973 * we're just allowing the client
2974 * to decide between SMB1 and SMB2
2975 * with the first negprot
2976 * packet.
2978 sconn->using_smb2 = true;
2981 /* Ensure child is set to blocking mode */
2982 set_blocking(sconn->sock,True);
2984 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2985 set_socket_options(sconn->sock, lp_socket_options());
2987 sa = (struct sockaddr *)(void *)&ss;
2988 sa_socklen = sizeof(ss);
2989 ret = getpeername(sconn->sock, sa, &sa_socklen);
2990 if (ret != 0) {
2991 int level = (errno == ENOTCONN)?2:0;
2992 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2993 exit_server_cleanly("getpeername() failed.\n");
2995 ret = tsocket_address_bsd_from_sockaddr(sconn,
2996 sa, sa_socklen,
2997 &remote_address);
2998 if (ret != 0) {
2999 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3000 __location__, strerror(errno)));
3001 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3004 sa = (struct sockaddr *)(void *)&ss;
3005 sa_socklen = sizeof(ss);
3006 ret = getsockname(sconn->sock, sa, &sa_socklen);
3007 if (ret != 0) {
3008 int level = (errno == ENOTCONN)?2:0;
3009 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3010 exit_server_cleanly("getsockname() failed.\n");
3012 ret = tsocket_address_bsd_from_sockaddr(sconn,
3013 sa, sa_socklen,
3014 &local_address);
3015 if (ret != 0) {
3016 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3017 __location__, strerror(errno)));
3018 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3021 sconn->local_address = local_address;
3022 sconn->remote_address = remote_address;
3024 if (tsocket_address_is_inet(remote_address, "ip")) {
3025 remaddr = tsocket_address_inet_addr_string(
3026 sconn->remote_address,
3027 talloc_tos());
3028 if (remaddr == NULL) {
3029 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3030 __location__, strerror(errno)));
3031 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3033 } else {
3034 remaddr = "0.0.0.0";
3037 /* this is needed so that we get decent entries
3038 in smbstatus for port 445 connects */
3039 set_remote_machine_name(remaddr, false);
3040 reload_services(sconn->msg_ctx, sconn->sock, true);
3043 * Before the first packet, check the global hosts allow/ hosts deny
3044 * parameters before doing any parsing of packets passed to us by the
3045 * client. This prevents attacks on our parsing code from hosts not in
3046 * the hosts allow list.
3049 ret = get_remote_hostname(remote_address,
3050 &rhost,
3051 talloc_tos());
3052 if (ret < 0) {
3053 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3054 __location__, strerror(errno)));
3055 exit_server_cleanly("get_remote_hostname failed.\n");
3057 if (strequal(rhost, "UNKNOWN")) {
3058 rhost = talloc_strdup(talloc_tos(), remaddr);
3060 sconn->remote_hostname = talloc_move(sconn, &rhost);
3062 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3063 sconn->remote_hostname,
3064 remaddr)) {
3066 * send a negative session response "not listening on calling
3067 * name"
3069 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3070 DEBUG( 1, ("Connection denied from %s to %s\n",
3071 tsocket_address_string(remote_address, talloc_tos()),
3072 tsocket_address_string(local_address, talloc_tos())));
3073 (void)srv_send_smb(sconn,(char *)buf, false,
3074 0, false, NULL);
3075 exit_server_cleanly("connection denied");
3078 DEBUG(10, ("Connection allowed from %s to %s\n",
3079 tsocket_address_string(remote_address, talloc_tos()),
3080 tsocket_address_string(local_address, talloc_tos())));
3082 init_modules();
3084 smb_perfcount_init();
3086 if (!init_account_policy()) {
3087 exit_server("Could not open account policy tdb.\n");
3090 if (*lp_rootdir()) {
3091 if (chroot(lp_rootdir()) != 0) {
3092 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3093 exit_server("Failed to chroot()");
3095 if (chdir("/") == -1) {
3096 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3097 exit_server("Failed to chroot()");
3099 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3102 if (!srv_init_signing(sconn)) {
3103 exit_server("Failed to init smb_signing");
3106 /* Setup oplocks */
3107 if (!init_oplocks(sconn->msg_ctx))
3108 exit_server("Failed to init oplocks");
3110 /* register our message handlers */
3111 messaging_register(sconn->msg_ctx, NULL,
3112 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3113 messaging_register(sconn->msg_ctx, NULL,
3114 MSG_SMB_CLOSE_FILE, msg_close_file);
3117 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3118 * MSGs to all child processes
3120 messaging_deregister(sconn->msg_ctx,
3121 MSG_DEBUG, NULL);
3122 messaging_register(sconn->msg_ctx, NULL,
3123 MSG_DEBUG, debug_message);
3125 if ((lp_keepalive() != 0)
3126 && !(event_add_idle(server_event_context(), NULL,
3127 timeval_set(lp_keepalive(), 0),
3128 "keepalive", keepalive_fn,
3129 NULL))) {
3130 DEBUG(0, ("Could not add keepalive event\n"));
3131 exit(1);
3134 if (!(event_add_idle(server_event_context(), NULL,
3135 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3136 "deadtime", deadtime_fn, sconn))) {
3137 DEBUG(0, ("Could not add deadtime event\n"));
3138 exit(1);
3141 if (!(event_add_idle(server_event_context(), NULL,
3142 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3143 "housekeeping", housekeeping_fn, sconn))) {
3144 DEBUG(0, ("Could not add housekeeping event\n"));
3145 exit(1);
3148 #ifdef CLUSTER_SUPPORT
3150 if (lp_clustering()) {
3152 * We need to tell ctdb about our client's TCP
3153 * connection, so that for failover ctdbd can send
3154 * tickle acks, triggering a reconnection by the
3155 * client.
3158 struct sockaddr_storage srv, clnt;
3160 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3161 NTSTATUS status;
3162 status = smbd_register_ips(sconn, &srv, &clnt);
3163 if (!NT_STATUS_IS_OK(status)) {
3164 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3165 nt_errstr(status)));
3167 } else
3169 DEBUG(0,("Unable to get tcp info for "
3170 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3171 strerror(errno)));
3175 #endif
3177 sconn->nbt.got_session = false;
3179 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3181 sconn->smb1.sessions.done_sesssetup = false;
3182 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3183 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3184 /* users from session setup */
3185 sconn->smb1.sessions.session_userlist = NULL;
3186 /* workgroup from session setup. */
3187 sconn->smb1.sessions.session_workgroup = NULL;
3188 /* this holds info on user ids that are already validated for this VC */
3189 sconn->smb1.sessions.validated_users = NULL;
3190 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3191 sconn->smb1.sessions.num_validated_vuids = 0;
3193 conn_init(sconn);
3194 if (!init_dptrs(sconn)) {
3195 exit_server("init_dptrs() failed");
3198 sconn->smb1.fde = event_add_fd(server_event_context(),
3199 sconn,
3200 sconn->sock,
3201 EVENT_FD_READ,
3202 smbd_server_connection_handler,
3203 sconn);
3204 if (!sconn->smb1.fde) {
3205 exit_server("failed to create smbd_server_connection fde");
3208 TALLOC_FREE(frame);
3210 while (True) {
3211 NTSTATUS status;
3213 frame = talloc_stackframe_pool(8192);
3215 errno = 0;
3217 status = smbd_server_connection_loop_once(sconn);
3218 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3219 !NT_STATUS_IS_OK(status)) {
3220 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3221 " exiting\n", nt_errstr(status)));
3222 break;
3225 TALLOC_FREE(frame);
3228 exit_server_cleanly(NULL);
3231 bool req_is_in_chain(struct smb_request *req)
3233 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3235 * We're right now handling a subsequent request, so we must
3236 * be in a chain
3238 return true;
3241 if (!is_andx_req(req->cmd)) {
3242 return false;
3245 if (req->wct < 2) {
3247 * Okay, an illegal request, but definitely not chained :-)
3249 return false;
3252 return (CVAL(req->vwv+0, 0) != 0xFF);