s3-smbd: Pass tevent context to smbd_server_connection_loop_once().
[Samba/gbeck.git] / source3 / smbd / process.c
blobfc6112c16130333fa0167d96997f6ed03c463b17
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"
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(
45 struct smbd_server_connection *sconn, uint64_t mid);
47 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
49 bool ok;
51 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
52 return true;
55 sconn->smb1.echo_handler.ref_count++;
57 if (sconn->smb1.echo_handler.ref_count > 1) {
58 return true;
61 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
63 do {
64 ok = fcntl_lock(
65 sconn->smb1.echo_handler.socket_lock_fd,
66 SMB_F_SETLKW, 0, 0, F_WRLCK);
67 } while (!ok && (errno == EINTR));
69 if (!ok) {
70 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
71 return false;
74 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
76 return true;
79 void smbd_lock_socket(struct smbd_server_connection *sconn)
81 if (!smbd_lock_socket_internal(sconn)) {
82 exit_server_cleanly("failed to lock socket");
86 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
88 bool ok;
90 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
91 return true;
94 sconn->smb1.echo_handler.ref_count--;
96 if (sconn->smb1.echo_handler.ref_count > 0) {
97 return true;
100 do {
101 ok = fcntl_lock(
102 sconn->smb1.echo_handler.socket_lock_fd,
103 SMB_F_SETLKW, 0, 0, F_UNLCK);
104 } while (!ok && (errno == EINTR));
106 if (!ok) {
107 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
108 return false;
111 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
113 return true;
116 void smbd_unlock_socket(struct smbd_server_connection *sconn)
118 if (!smbd_unlock_socket_internal(sconn)) {
119 exit_server_cleanly("failed to unlock socket");
123 /* Accessor function for smb_read_error for smbd functions. */
125 /****************************************************************************
126 Send an smb to a fd.
127 ****************************************************************************/
129 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
130 bool do_signing, uint32_t seqnum,
131 bool do_encrypt,
132 struct smb_perfcount_data *pcd)
134 size_t len = 0;
135 size_t nwritten=0;
136 ssize_t ret;
137 char *buf_out = buffer;
139 smbd_lock_socket(sconn);
141 if (do_signing) {
142 /* Sign the outgoing packet if required. */
143 srv_calculate_sign_mac(sconn, buf_out, seqnum);
146 if (do_encrypt) {
147 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
148 if (!NT_STATUS_IS_OK(status)) {
149 DEBUG(0, ("send_smb: SMB encryption failed "
150 "on outgoing packet! Error %s\n",
151 nt_errstr(status) ));
152 goto out;
156 len = smb_len(buf_out) + 4;
158 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
159 if (ret <= 0) {
161 char addr[INET6_ADDRSTRLEN];
163 * Try and give an error message saying what
164 * client failed.
166 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
167 (int)sys_getpid(), (int)len,
168 get_peer_addr(sconn->sock, addr, sizeof(addr)),
169 (int)ret, strerror(errno) ));
171 srv_free_enc_buffer(buf_out);
172 goto out;
175 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
176 srv_free_enc_buffer(buf_out);
177 out:
178 SMB_PERFCOUNT_END(pcd);
180 smbd_unlock_socket(sconn);
181 return true;
184 /*******************************************************************
185 Setup the word count and byte count for a smb message.
186 ********************************************************************/
188 int srv_set_message(char *buf,
189 int num_words,
190 int num_bytes,
191 bool zero)
193 if (zero && (num_words || num_bytes)) {
194 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
196 SCVAL(buf,smb_wct,num_words);
197 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
198 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
199 return (smb_size + num_words*2 + num_bytes);
202 static bool valid_smb_header(const uint8_t *inbuf)
204 if (is_encrypted_packet(inbuf)) {
205 return true;
208 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
209 * but it just looks weird to call strncmp for this one.
211 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
214 /* Socket functions for smbd packet processing. */
216 static bool valid_packet_size(size_t len)
219 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
220 * of header. Don't print the error if this fits.... JRA.
223 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
224 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
225 (unsigned long)len));
226 return false;
228 return true;
231 static NTSTATUS read_packet_remainder(int fd, char *buffer,
232 unsigned int timeout, ssize_t len)
234 NTSTATUS status;
236 if (len <= 0) {
237 return NT_STATUS_OK;
240 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
241 if (!NT_STATUS_IS_OK(status)) {
242 char addr[INET6_ADDRSTRLEN];
243 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
244 "error = %s.\n",
245 get_peer_addr(fd, addr, sizeof(addr)),
246 nt_errstr(status)));
248 return status;
251 /****************************************************************************
252 Attempt a zerocopy writeX read. We know here that len > smb_size-4
253 ****************************************************************************/
256 * Unfortunately, earlier versions of smbclient/libsmbclient
257 * don't send this "standard" writeX header. I've fixed this
258 * for 3.2 but we'll use the old method with earlier versions.
259 * Windows and CIFSFS at least use this standard size. Not
260 * sure about MacOSX.
263 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
264 (2*14) + /* word count (including bcc) */ \
265 1 /* pad byte */)
267 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
268 const char lenbuf[4],
269 struct smbd_server_connection *sconn,
270 int sock,
271 char **buffer,
272 unsigned int timeout,
273 size_t *p_unread,
274 size_t *len_ret)
276 /* Size of a WRITEX call (+4 byte len). */
277 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
278 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
279 ssize_t toread;
280 NTSTATUS status;
282 memcpy(writeX_header, lenbuf, 4);
284 status = read_fd_with_timeout(
285 sock, writeX_header + 4,
286 STANDARD_WRITE_AND_X_HEADER_SIZE,
287 STANDARD_WRITE_AND_X_HEADER_SIZE,
288 timeout, NULL);
290 if (!NT_STATUS_IS_OK(status)) {
291 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
292 "error = %s.\n",
293 tsocket_address_string(sconn->remote_address,
294 talloc_tos()),
295 nt_errstr(status)));
296 return status;
300 * Ok - now try and see if this is a possible
301 * valid writeX call.
304 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
306 * If the data offset is beyond what
307 * we've read, drain the extra bytes.
309 uint16_t doff = SVAL(writeX_header,smb_vwv11);
310 ssize_t newlen;
312 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
313 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
314 if (drain_socket(sock, drain) != drain) {
315 smb_panic("receive_smb_raw_talloc_partial_read:"
316 " failed to drain pending bytes");
318 } else {
319 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
322 /* Spoof down the length and null out the bcc. */
323 set_message_bcc(writeX_header, 0);
324 newlen = smb_len(writeX_header);
326 /* Copy the header we've written. */
328 *buffer = (char *)talloc_memdup(mem_ctx,
329 writeX_header,
330 sizeof(writeX_header));
332 if (*buffer == NULL) {
333 DEBUG(0, ("Could not allocate inbuf of length %d\n",
334 (int)sizeof(writeX_header)));
335 return NT_STATUS_NO_MEMORY;
338 /* Work out the remaining bytes. */
339 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
340 *len_ret = newlen + 4;
341 return NT_STATUS_OK;
344 if (!valid_packet_size(len)) {
345 return NT_STATUS_INVALID_PARAMETER;
349 * Not a valid writeX call. Just do the standard
350 * talloc and return.
353 *buffer = talloc_array(mem_ctx, char, len+4);
355 if (*buffer == NULL) {
356 DEBUG(0, ("Could not allocate inbuf of length %d\n",
357 (int)len+4));
358 return NT_STATUS_NO_MEMORY;
361 /* Copy in what we already read. */
362 memcpy(*buffer,
363 writeX_header,
364 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
365 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
367 if(toread > 0) {
368 status = read_packet_remainder(
369 sock,
370 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
371 timeout, toread);
373 if (!NT_STATUS_IS_OK(status)) {
374 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
375 nt_errstr(status)));
376 return status;
380 *len_ret = len + 4;
381 return NT_STATUS_OK;
384 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
385 struct smbd_server_connection *sconn,
386 int sock,
387 char **buffer, unsigned int timeout,
388 size_t *p_unread, size_t *plen)
390 char lenbuf[4];
391 size_t len;
392 int min_recv_size = lp_min_receive_file_size();
393 NTSTATUS status;
395 *p_unread = 0;
397 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
398 &len);
399 if (!NT_STATUS_IS_OK(status)) {
400 return status;
403 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
404 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
405 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
406 !srv_is_signing_active(sconn) &&
407 sconn->smb1.echo_handler.trusted_fde == NULL) {
409 return receive_smb_raw_talloc_partial_read(
410 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
411 p_unread, plen);
414 if (!valid_packet_size(len)) {
415 return NT_STATUS_INVALID_PARAMETER;
419 * The +4 here can't wrap, we've checked the length above already.
422 *buffer = talloc_array(mem_ctx, char, len+4);
424 if (*buffer == NULL) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)len+4));
427 return NT_STATUS_NO_MEMORY;
430 memcpy(*buffer, lenbuf, sizeof(lenbuf));
432 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
433 if (!NT_STATUS_IS_OK(status)) {
434 return status;
437 *plen = len + 4;
438 return NT_STATUS_OK;
441 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
442 struct smbd_server_connection *sconn,
443 int sock,
444 char **buffer, unsigned int timeout,
445 size_t *p_unread, bool *p_encrypted,
446 size_t *p_len,
447 uint32_t *seqnum,
448 bool trusted_channel)
450 size_t len = 0;
451 NTSTATUS status;
453 *p_encrypted = false;
455 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
456 p_unread, &len);
457 if (!NT_STATUS_IS_OK(status)) {
458 DEBUG(1, ("read_smb_length_return_keepalive failed for "
459 "client %s read error = %s.\n",
460 tsocket_address_string(sconn->remote_address,
461 talloc_tos()),
462 nt_errstr(status)));
463 return status;
466 if (is_encrypted_packet((uint8_t *)*buffer)) {
467 status = srv_decrypt_buffer(*buffer);
468 if (!NT_STATUS_IS_OK(status)) {
469 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
470 "incoming packet! Error %s\n",
471 nt_errstr(status) ));
472 return status;
474 *p_encrypted = true;
477 /* Check the incoming SMB signature. */
478 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
479 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
480 "incoming packet!\n"));
481 return NT_STATUS_INVALID_NETWORK_RESPONSE;
484 *p_len = len;
485 return NT_STATUS_OK;
489 * Initialize a struct smb_request from an inbuf
492 static bool init_smb_request(struct smb_request *req,
493 struct smbd_server_connection *sconn,
494 const uint8 *inbuf,
495 size_t unread_bytes, bool encrypted,
496 uint32_t seqnum)
498 size_t req_size = smb_len(inbuf) + 4;
499 /* Ensure we have at least smb_size bytes. */
500 if (req_size < smb_size) {
501 DEBUG(0,("init_smb_request: invalid request size %u\n",
502 (unsigned int)req_size ));
503 return false;
505 req->cmd = CVAL(inbuf, smb_com);
506 req->flags2 = SVAL(inbuf, smb_flg2);
507 req->smbpid = SVAL(inbuf, smb_pid);
508 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
509 req->seqnum = seqnum;
510 req->vuid = SVAL(inbuf, smb_uid);
511 req->tid = SVAL(inbuf, smb_tid);
512 req->wct = CVAL(inbuf, smb_wct);
513 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
514 req->buflen = smb_buflen(inbuf);
515 req->buf = (const uint8_t *)smb_buf_const(inbuf);
516 req->unread_bytes = unread_bytes;
517 req->encrypted = encrypted;
518 req->sconn = sconn;
519 req->conn = conn_find(sconn,req->tid);
520 req->chain_fsp = NULL;
521 req->chain_outbuf = NULL;
522 req->done = false;
523 req->smb2req = NULL;
524 smb_init_perfcount_data(&req->pcd);
526 /* Ensure we have at least wct words and 2 bytes of bcc. */
527 if (smb_size + req->wct*2 > req_size) {
528 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
529 (unsigned int)req->wct,
530 (unsigned int)req_size));
531 return false;
533 /* Ensure bcc is correct. */
534 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
535 DEBUG(0,("init_smb_request: invalid bcc number %u "
536 "(wct = %u, size %u)\n",
537 (unsigned int)req->buflen,
538 (unsigned int)req->wct,
539 (unsigned int)req_size));
540 return false;
543 req->outbuf = NULL;
544 return true;
547 static void process_smb(struct smbd_server_connection *conn,
548 uint8_t *inbuf, size_t nread, size_t unread_bytes,
549 uint32_t seqnum, bool encrypted,
550 struct smb_perfcount_data *deferred_pcd);
552 static void smbd_deferred_open_timer(struct event_context *ev,
553 struct timed_event *te,
554 struct timeval _tval,
555 void *private_data)
557 struct pending_message_list *msg = talloc_get_type(private_data,
558 struct pending_message_list);
559 TALLOC_CTX *mem_ctx = talloc_tos();
560 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
561 uint8_t *inbuf;
563 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
564 msg->buf.length);
565 if (inbuf == NULL) {
566 exit_server("smbd_deferred_open_timer: talloc failed\n");
567 return;
570 /* We leave this message on the queue so the open code can
571 know this is a retry. */
572 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
573 (unsigned long long)mid ));
575 /* Mark the message as processed so this is not
576 * re-processed in error. */
577 msg->processed = true;
579 process_smb(smbd_server_conn, inbuf,
580 msg->buf.length, 0,
581 msg->seqnum, msg->encrypted, &msg->pcd);
583 /* If it's still there and was processed, remove it. */
584 msg = get_deferred_open_message_smb(smbd_server_conn, mid);
585 if (msg && msg->processed) {
586 remove_deferred_open_message_smb(smbd_server_conn, mid);
590 /****************************************************************************
591 Function to push a message onto the tail of a linked list of smb messages ready
592 for processing.
593 ****************************************************************************/
595 static bool push_queued_message(struct smb_request *req,
596 struct timeval request_time,
597 struct timeval end_time,
598 char *private_data, size_t private_len)
600 int msg_len = smb_len(req->inbuf) + 4;
601 struct pending_message_list *msg;
603 msg = talloc_zero(NULL, struct pending_message_list);
605 if(msg == NULL) {
606 DEBUG(0,("push_message: malloc fail (1)\n"));
607 return False;
610 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
611 if(msg->buf.data == NULL) {
612 DEBUG(0,("push_message: malloc fail (2)\n"));
613 TALLOC_FREE(msg);
614 return False;
617 msg->request_time = request_time;
618 msg->seqnum = req->seqnum;
619 msg->encrypted = req->encrypted;
620 msg->processed = false;
621 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
623 if (private_data) {
624 msg->private_data = data_blob_talloc(msg, private_data,
625 private_len);
626 if (msg->private_data.data == NULL) {
627 DEBUG(0,("push_message: malloc fail (3)\n"));
628 TALLOC_FREE(msg);
629 return False;
633 msg->te = event_add_timed(server_event_context(),
634 msg,
635 end_time,
636 smbd_deferred_open_timer,
637 msg);
638 if (!msg->te) {
639 DEBUG(0,("push_message: event_add_timed failed\n"));
640 TALLOC_FREE(msg);
641 return false;
644 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
645 struct pending_message_list *);
647 DEBUG(10,("push_message: pushed message length %u on "
648 "deferred_open_queue\n", (unsigned int)msg_len));
650 return True;
653 /****************************************************************************
654 Function to delete a sharing violation open message by mid.
655 ****************************************************************************/
657 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
658 uint64_t mid)
660 struct pending_message_list *pml;
662 if (sconn->using_smb2) {
663 remove_deferred_open_message_smb2(sconn, mid);
664 return;
667 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
668 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
669 DEBUG(10,("remove_deferred_open_message_smb: "
670 "deleting mid %llu len %u\n",
671 (unsigned long long)mid,
672 (unsigned int)pml->buf.length ));
673 DLIST_REMOVE(sconn->deferred_open_queue, pml);
674 TALLOC_FREE(pml);
675 return;
680 /****************************************************************************
681 Move a sharing violation open retry message to the front of the list and
682 schedule it for immediate processing.
683 ****************************************************************************/
685 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
686 uint64_t mid)
688 struct pending_message_list *pml;
689 int i = 0;
691 if (sconn->using_smb2) {
692 schedule_deferred_open_message_smb2(sconn, mid);
693 return;
696 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
697 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
699 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
700 "msg_mid = %llu\n",
701 i++,
702 (unsigned long long)msg_mid ));
704 if (mid == msg_mid) {
705 struct timed_event *te;
707 if (pml->processed) {
708 /* A processed message should not be
709 * rescheduled. */
710 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
711 "message mid %llu was already processed\n",
712 (unsigned long long)msg_mid ));
713 continue;
716 DEBUG(10,("schedule_deferred_open_message_smb: "
717 "scheduling mid %llu\n",
718 (unsigned long long)mid ));
720 te = event_add_timed(server_event_context(),
721 pml,
722 timeval_zero(),
723 smbd_deferred_open_timer,
724 pml);
725 if (!te) {
726 DEBUG(10,("schedule_deferred_open_message_smb: "
727 "event_add_timed() failed, "
728 "skipping mid %llu\n",
729 (unsigned long long)msg_mid ));
732 TALLOC_FREE(pml->te);
733 pml->te = te;
734 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
735 return;
739 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
740 "find message mid %llu\n",
741 (unsigned long long)mid ));
744 /****************************************************************************
745 Return true if this mid is on the deferred queue and was not yet processed.
746 ****************************************************************************/
748 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
750 struct pending_message_list *pml;
752 if (sconn->using_smb2) {
753 return open_was_deferred_smb2(sconn, mid);
756 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
757 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
758 return True;
761 return False;
764 /****************************************************************************
765 Return the message queued by this mid.
766 ****************************************************************************/
768 static struct pending_message_list *get_deferred_open_message_smb(
769 struct smbd_server_connection *sconn, uint64_t mid)
771 struct pending_message_list *pml;
773 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
774 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
775 return pml;
778 return NULL;
781 /****************************************************************************
782 Get the state data queued by this mid.
783 ****************************************************************************/
785 bool get_deferred_open_message_state(struct smb_request *smbreq,
786 struct timeval *p_request_time,
787 void **pp_state)
789 struct pending_message_list *pml;
791 if (smbd_server_conn->using_smb2) {
792 return get_deferred_open_message_state_smb2(smbreq->smb2req,
793 p_request_time,
794 pp_state);
797 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
798 if (!pml) {
799 return false;
801 if (p_request_time) {
802 *p_request_time = pml->request_time;
804 if (pp_state) {
805 *pp_state = (void *)pml->private_data.data;
807 return true;
810 /****************************************************************************
811 Function to push a deferred open smb message onto a linked list of local smb
812 messages ready for processing.
813 ****************************************************************************/
815 bool push_deferred_open_message_smb(struct smb_request *req,
816 struct timeval request_time,
817 struct timeval timeout,
818 struct file_id id,
819 char *private_data, size_t priv_len)
821 struct timeval end_time;
823 if (req->smb2req) {
824 return push_deferred_open_message_smb2(req->smb2req,
825 request_time,
826 timeout,
828 private_data,
829 priv_len);
832 if (req->unread_bytes) {
833 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
834 "unread_bytes = %u\n",
835 (unsigned int)req->unread_bytes ));
836 smb_panic("push_deferred_open_message_smb: "
837 "logic error unread_bytes != 0" );
840 end_time = timeval_sum(&request_time, &timeout);
842 DEBUG(10,("push_deferred_open_message_smb: pushing message "
843 "len %u mid %llu timeout time [%u.%06u]\n",
844 (unsigned int) smb_len(req->inbuf)+4,
845 (unsigned long long)req->mid,
846 (unsigned int)end_time.tv_sec,
847 (unsigned int)end_time.tv_usec));
849 return push_queued_message(req, request_time, end_time,
850 private_data, priv_len);
853 static void smbd_sig_term_handler(struct tevent_context *ev,
854 struct tevent_signal *se,
855 int signum,
856 int count,
857 void *siginfo,
858 void *private_data)
860 exit_server_cleanly("termination signal");
863 void smbd_setup_sig_term_handler(void)
865 struct tevent_signal *se;
867 se = tevent_add_signal(server_event_context(),
868 server_event_context(),
869 SIGTERM, 0,
870 smbd_sig_term_handler,
871 NULL);
872 if (!se) {
873 exit_server("failed to setup SIGTERM handler");
877 static void smbd_sig_hup_handler(struct tevent_context *ev,
878 struct tevent_signal *se,
879 int signum,
880 int count,
881 void *siginfo,
882 void *private_data)
884 struct messaging_context *msg_ctx = talloc_get_type_abort(
885 private_data, struct messaging_context);
886 change_to_root_user();
887 DEBUG(1,("Reloading services after SIGHUP\n"));
888 reload_services(msg_ctx, smbd_server_conn->sock, False);
889 if (am_parent) {
890 printing_subsystem_update(ev, msg_ctx);
894 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
895 struct messaging_context *msg_ctx)
897 struct tevent_signal *se;
899 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
900 msg_ctx);
901 if (!se) {
902 exit_server("failed to setup SIGHUP handler");
906 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
907 struct smbd_server_connection *conn)
909 int timeout;
910 int num_pfds = 0;
911 int ret;
912 bool retry;
914 timeout = SMBD_SELECT_TIMEOUT * 1000;
917 * Are there any timed events waiting ? If so, ensure we don't
918 * select for longer than it would take to wait for them.
921 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
923 /* Process a signal and timed events now... */
924 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
925 return NT_STATUS_RETRY;
929 int sav;
930 START_PROFILE(smbd_idle);
932 ret = sys_poll(conn->pfds, num_pfds, timeout);
933 sav = errno;
935 END_PROFILE(smbd_idle);
936 errno = sav;
939 if (ret == -1) {
940 if (errno == EINTR) {
941 return NT_STATUS_RETRY;
943 return map_nt_error_from_unix(errno);
946 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
947 if (retry) {
948 return NT_STATUS_RETRY;
951 /* Did we timeout ? */
952 if (ret == 0) {
953 return NT_STATUS_RETRY;
956 /* should not be reached */
957 return NT_STATUS_INTERNAL_ERROR;
961 * Only allow 5 outstanding trans requests. We're allocating memory, so
962 * prevent a DoS.
965 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
967 int count = 0;
968 for (; list != NULL; list = list->next) {
970 if (list->mid == mid) {
971 return NT_STATUS_INVALID_PARAMETER;
974 count += 1;
976 if (count > 5) {
977 return NT_STATUS_INSUFFICIENT_RESOURCES;
980 return NT_STATUS_OK;
984 These flags determine some of the permissions required to do an operation
986 Note that I don't set NEED_WRITE on some write operations because they
987 are used by some brain-dead clients when printing, and I don't want to
988 force write permissions on print services.
990 #define AS_USER (1<<0)
991 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
992 #define TIME_INIT (1<<2)
993 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
994 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
995 #define DO_CHDIR (1<<6)
998 define a list of possible SMB messages and their corresponding
999 functions. Any message that has a NULL function is unimplemented -
1000 please feel free to contribute implementations!
1002 static const struct smb_message_struct {
1003 const char *name;
1004 void (*fn)(struct smb_request *req);
1005 int flags;
1006 } smb_messages[256] = {
1008 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1009 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1010 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1011 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1012 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1013 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1014 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1015 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1016 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1017 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1018 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1019 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1020 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1021 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1022 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1023 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1024 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1025 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1026 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1027 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1028 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1029 /* 0x15 */ { NULL, NULL, 0 },
1030 /* 0x16 */ { NULL, NULL, 0 },
1031 /* 0x17 */ { NULL, NULL, 0 },
1032 /* 0x18 */ { NULL, NULL, 0 },
1033 /* 0x19 */ { NULL, NULL, 0 },
1034 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1035 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1036 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1037 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1038 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1039 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1040 /* 0x20 */ { "SMBwritec", NULL,0},
1041 /* 0x21 */ { NULL, NULL, 0 },
1042 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1043 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1044 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1045 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1046 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1047 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1048 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1049 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1050 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1051 /* 0x2b */ { "SMBecho",reply_echo,0},
1052 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1053 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1054 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1055 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1056 /* 0x30 */ { NULL, NULL, 0 },
1057 /* 0x31 */ { NULL, NULL, 0 },
1058 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1059 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1060 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1061 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1062 /* 0x36 */ { NULL, NULL, 0 },
1063 /* 0x37 */ { NULL, NULL, 0 },
1064 /* 0x38 */ { NULL, NULL, 0 },
1065 /* 0x39 */ { NULL, NULL, 0 },
1066 /* 0x3a */ { NULL, NULL, 0 },
1067 /* 0x3b */ { NULL, NULL, 0 },
1068 /* 0x3c */ { NULL, NULL, 0 },
1069 /* 0x3d */ { NULL, NULL, 0 },
1070 /* 0x3e */ { NULL, NULL, 0 },
1071 /* 0x3f */ { NULL, NULL, 0 },
1072 /* 0x40 */ { NULL, NULL, 0 },
1073 /* 0x41 */ { NULL, NULL, 0 },
1074 /* 0x42 */ { NULL, NULL, 0 },
1075 /* 0x43 */ { NULL, NULL, 0 },
1076 /* 0x44 */ { NULL, NULL, 0 },
1077 /* 0x45 */ { NULL, NULL, 0 },
1078 /* 0x46 */ { NULL, NULL, 0 },
1079 /* 0x47 */ { NULL, NULL, 0 },
1080 /* 0x48 */ { NULL, NULL, 0 },
1081 /* 0x49 */ { NULL, NULL, 0 },
1082 /* 0x4a */ { NULL, NULL, 0 },
1083 /* 0x4b */ { NULL, NULL, 0 },
1084 /* 0x4c */ { NULL, NULL, 0 },
1085 /* 0x4d */ { NULL, NULL, 0 },
1086 /* 0x4e */ { NULL, NULL, 0 },
1087 /* 0x4f */ { NULL, NULL, 0 },
1088 /* 0x50 */ { NULL, NULL, 0 },
1089 /* 0x51 */ { NULL, NULL, 0 },
1090 /* 0x52 */ { NULL, NULL, 0 },
1091 /* 0x53 */ { NULL, NULL, 0 },
1092 /* 0x54 */ { NULL, NULL, 0 },
1093 /* 0x55 */ { NULL, NULL, 0 },
1094 /* 0x56 */ { NULL, NULL, 0 },
1095 /* 0x57 */ { NULL, NULL, 0 },
1096 /* 0x58 */ { NULL, NULL, 0 },
1097 /* 0x59 */ { NULL, NULL, 0 },
1098 /* 0x5a */ { NULL, NULL, 0 },
1099 /* 0x5b */ { NULL, NULL, 0 },
1100 /* 0x5c */ { NULL, NULL, 0 },
1101 /* 0x5d */ { NULL, NULL, 0 },
1102 /* 0x5e */ { NULL, NULL, 0 },
1103 /* 0x5f */ { NULL, NULL, 0 },
1104 /* 0x60 */ { NULL, NULL, 0 },
1105 /* 0x61 */ { NULL, NULL, 0 },
1106 /* 0x62 */ { NULL, NULL, 0 },
1107 /* 0x63 */ { NULL, NULL, 0 },
1108 /* 0x64 */ { NULL, NULL, 0 },
1109 /* 0x65 */ { NULL, NULL, 0 },
1110 /* 0x66 */ { NULL, NULL, 0 },
1111 /* 0x67 */ { NULL, NULL, 0 },
1112 /* 0x68 */ { NULL, NULL, 0 },
1113 /* 0x69 */ { NULL, NULL, 0 },
1114 /* 0x6a */ { NULL, NULL, 0 },
1115 /* 0x6b */ { NULL, NULL, 0 },
1116 /* 0x6c */ { NULL, NULL, 0 },
1117 /* 0x6d */ { NULL, NULL, 0 },
1118 /* 0x6e */ { NULL, NULL, 0 },
1119 /* 0x6f */ { NULL, NULL, 0 },
1120 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1121 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1122 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1123 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1124 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1125 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1126 /* 0x76 */ { NULL, NULL, 0 },
1127 /* 0x77 */ { NULL, NULL, 0 },
1128 /* 0x78 */ { NULL, NULL, 0 },
1129 /* 0x79 */ { NULL, NULL, 0 },
1130 /* 0x7a */ { NULL, NULL, 0 },
1131 /* 0x7b */ { NULL, NULL, 0 },
1132 /* 0x7c */ { NULL, NULL, 0 },
1133 /* 0x7d */ { NULL, NULL, 0 },
1134 /* 0x7e */ { NULL, NULL, 0 },
1135 /* 0x7f */ { NULL, NULL, 0 },
1136 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1137 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1138 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1139 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1140 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1141 /* 0x85 */ { NULL, NULL, 0 },
1142 /* 0x86 */ { NULL, NULL, 0 },
1143 /* 0x87 */ { NULL, NULL, 0 },
1144 /* 0x88 */ { NULL, NULL, 0 },
1145 /* 0x89 */ { NULL, NULL, 0 },
1146 /* 0x8a */ { NULL, NULL, 0 },
1147 /* 0x8b */ { NULL, NULL, 0 },
1148 /* 0x8c */ { NULL, NULL, 0 },
1149 /* 0x8d */ { NULL, NULL, 0 },
1150 /* 0x8e */ { NULL, NULL, 0 },
1151 /* 0x8f */ { NULL, NULL, 0 },
1152 /* 0x90 */ { NULL, NULL, 0 },
1153 /* 0x91 */ { NULL, NULL, 0 },
1154 /* 0x92 */ { NULL, NULL, 0 },
1155 /* 0x93 */ { NULL, NULL, 0 },
1156 /* 0x94 */ { NULL, NULL, 0 },
1157 /* 0x95 */ { NULL, NULL, 0 },
1158 /* 0x96 */ { NULL, NULL, 0 },
1159 /* 0x97 */ { NULL, NULL, 0 },
1160 /* 0x98 */ { NULL, NULL, 0 },
1161 /* 0x99 */ { NULL, NULL, 0 },
1162 /* 0x9a */ { NULL, NULL, 0 },
1163 /* 0x9b */ { NULL, NULL, 0 },
1164 /* 0x9c */ { NULL, NULL, 0 },
1165 /* 0x9d */ { NULL, NULL, 0 },
1166 /* 0x9e */ { NULL, NULL, 0 },
1167 /* 0x9f */ { NULL, NULL, 0 },
1168 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1169 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1170 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1171 /* 0xa3 */ { NULL, NULL, 0 },
1172 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1173 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1174 /* 0xa6 */ { NULL, NULL, 0 },
1175 /* 0xa7 */ { NULL, NULL, 0 },
1176 /* 0xa8 */ { NULL, NULL, 0 },
1177 /* 0xa9 */ { NULL, NULL, 0 },
1178 /* 0xaa */ { NULL, NULL, 0 },
1179 /* 0xab */ { NULL, NULL, 0 },
1180 /* 0xac */ { NULL, NULL, 0 },
1181 /* 0xad */ { NULL, NULL, 0 },
1182 /* 0xae */ { NULL, NULL, 0 },
1183 /* 0xaf */ { NULL, NULL, 0 },
1184 /* 0xb0 */ { NULL, NULL, 0 },
1185 /* 0xb1 */ { NULL, NULL, 0 },
1186 /* 0xb2 */ { NULL, NULL, 0 },
1187 /* 0xb3 */ { NULL, NULL, 0 },
1188 /* 0xb4 */ { NULL, NULL, 0 },
1189 /* 0xb5 */ { NULL, NULL, 0 },
1190 /* 0xb6 */ { NULL, NULL, 0 },
1191 /* 0xb7 */ { NULL, NULL, 0 },
1192 /* 0xb8 */ { NULL, NULL, 0 },
1193 /* 0xb9 */ { NULL, NULL, 0 },
1194 /* 0xba */ { NULL, NULL, 0 },
1195 /* 0xbb */ { NULL, NULL, 0 },
1196 /* 0xbc */ { NULL, NULL, 0 },
1197 /* 0xbd */ { NULL, NULL, 0 },
1198 /* 0xbe */ { NULL, NULL, 0 },
1199 /* 0xbf */ { NULL, NULL, 0 },
1200 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1201 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1202 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1203 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1204 /* 0xc4 */ { NULL, NULL, 0 },
1205 /* 0xc5 */ { NULL, NULL, 0 },
1206 /* 0xc6 */ { NULL, NULL, 0 },
1207 /* 0xc7 */ { NULL, NULL, 0 },
1208 /* 0xc8 */ { NULL, NULL, 0 },
1209 /* 0xc9 */ { NULL, NULL, 0 },
1210 /* 0xca */ { NULL, NULL, 0 },
1211 /* 0xcb */ { NULL, NULL, 0 },
1212 /* 0xcc */ { NULL, NULL, 0 },
1213 /* 0xcd */ { NULL, NULL, 0 },
1214 /* 0xce */ { NULL, NULL, 0 },
1215 /* 0xcf */ { NULL, NULL, 0 },
1216 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1217 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1218 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1219 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1220 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1221 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1222 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1223 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1224 /* 0xd8 */ { NULL, NULL, 0 },
1225 /* 0xd9 */ { NULL, NULL, 0 },
1226 /* 0xda */ { NULL, NULL, 0 },
1227 /* 0xdb */ { NULL, NULL, 0 },
1228 /* 0xdc */ { NULL, NULL, 0 },
1229 /* 0xdd */ { NULL, NULL, 0 },
1230 /* 0xde */ { NULL, NULL, 0 },
1231 /* 0xdf */ { NULL, NULL, 0 },
1232 /* 0xe0 */ { NULL, NULL, 0 },
1233 /* 0xe1 */ { NULL, NULL, 0 },
1234 /* 0xe2 */ { NULL, NULL, 0 },
1235 /* 0xe3 */ { NULL, NULL, 0 },
1236 /* 0xe4 */ { NULL, NULL, 0 },
1237 /* 0xe5 */ { NULL, NULL, 0 },
1238 /* 0xe6 */ { NULL, NULL, 0 },
1239 /* 0xe7 */ { NULL, NULL, 0 },
1240 /* 0xe8 */ { NULL, NULL, 0 },
1241 /* 0xe9 */ { NULL, NULL, 0 },
1242 /* 0xea */ { NULL, NULL, 0 },
1243 /* 0xeb */ { NULL, NULL, 0 },
1244 /* 0xec */ { NULL, NULL, 0 },
1245 /* 0xed */ { NULL, NULL, 0 },
1246 /* 0xee */ { NULL, NULL, 0 },
1247 /* 0xef */ { NULL, NULL, 0 },
1248 /* 0xf0 */ { NULL, NULL, 0 },
1249 /* 0xf1 */ { NULL, NULL, 0 },
1250 /* 0xf2 */ { NULL, NULL, 0 },
1251 /* 0xf3 */ { NULL, NULL, 0 },
1252 /* 0xf4 */ { NULL, NULL, 0 },
1253 /* 0xf5 */ { NULL, NULL, 0 },
1254 /* 0xf6 */ { NULL, NULL, 0 },
1255 /* 0xf7 */ { NULL, NULL, 0 },
1256 /* 0xf8 */ { NULL, NULL, 0 },
1257 /* 0xf9 */ { NULL, NULL, 0 },
1258 /* 0xfa */ { NULL, NULL, 0 },
1259 /* 0xfb */ { NULL, NULL, 0 },
1260 /* 0xfc */ { NULL, NULL, 0 },
1261 /* 0xfd */ { NULL, NULL, 0 },
1262 /* 0xfe */ { NULL, NULL, 0 },
1263 /* 0xff */ { NULL, NULL, 0 }
1267 /*******************************************************************
1268 allocate and initialize a reply packet
1269 ********************************************************************/
1271 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1272 const char *inbuf, char **outbuf, uint8_t num_words,
1273 uint32_t num_bytes)
1276 * Protect against integer wrap
1278 if ((num_bytes > 0xffffff)
1279 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1280 char *msg;
1281 if (asprintf(&msg, "num_bytes too large: %u",
1282 (unsigned)num_bytes) == -1) {
1283 msg = discard_const_p(char, "num_bytes too large");
1285 smb_panic(msg);
1288 *outbuf = talloc_array(mem_ctx, char,
1289 smb_size + num_words*2 + num_bytes);
1290 if (*outbuf == NULL) {
1291 return false;
1294 construct_reply_common(req, inbuf, *outbuf);
1295 srv_set_message(*outbuf, num_words, num_bytes, false);
1297 * Zero out the word area, the caller has to take care of the bcc area
1298 * himself
1300 if (num_words != 0) {
1301 memset(*outbuf + smb_vwv0, 0, num_words*2);
1304 return true;
1307 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1309 char *outbuf;
1310 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1311 num_bytes)) {
1312 smb_panic("could not allocate output buffer\n");
1314 req->outbuf = (uint8_t *)outbuf;
1318 /*******************************************************************
1319 Dump a packet to a file.
1320 ********************************************************************/
1322 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1324 int fd, i;
1325 char *fname = NULL;
1326 if (DEBUGLEVEL < 50) {
1327 return;
1330 if (len < 4) len = smb_len(data)+4;
1331 for (i=1;i<100;i++) {
1332 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1333 type ? "req" : "resp") == -1) {
1334 return;
1336 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1337 if (fd != -1 || errno != EEXIST) break;
1339 if (fd != -1) {
1340 ssize_t ret = write(fd, data, len);
1341 if (ret != len)
1342 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1343 close(fd);
1344 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1346 SAFE_FREE(fname);
1349 /****************************************************************************
1350 Prepare everything for calling the actual request function, and potentially
1351 call the request function via the "new" interface.
1353 Return False if the "legacy" function needs to be called, everything is
1354 prepared.
1356 Return True if we're done.
1358 I know this API sucks, but it is the one with the least code change I could
1359 find.
1360 ****************************************************************************/
1362 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1364 int flags;
1365 uint16 session_tag;
1366 connection_struct *conn = NULL;
1367 struct smbd_server_connection *sconn = req->sconn;
1368 char *raddr;
1370 errno = 0;
1372 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1373 * so subtract 4 from it. */
1374 if (!valid_smb_header(req->inbuf)
1375 || (size < (smb_size - 4))) {
1376 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1377 smb_len(req->inbuf)));
1378 exit_server_cleanly("Non-SMB packet");
1381 if (smb_messages[type].fn == NULL) {
1382 DEBUG(0,("Unknown message type %d!\n",type));
1383 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1384 reply_unknown_new(req, type);
1385 return NULL;
1388 flags = smb_messages[type].flags;
1390 /* In share mode security we must ignore the vuid. */
1391 session_tag = (lp_security() == SEC_SHARE)
1392 ? UID_FIELD_INVALID : req->vuid;
1393 conn = req->conn;
1395 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1396 (int)sys_getpid(), (unsigned long)conn));
1398 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1400 /* Ensure this value is replaced in the incoming packet. */
1401 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1404 * Ensure the correct username is in current_user_info. This is a
1405 * really ugly bugfix for problems with multiple session_setup_and_X's
1406 * being done and allowing %U and %G substitutions to work correctly.
1407 * There is a reason this code is done here, don't move it unless you
1408 * know what you're doing... :-).
1409 * JRA.
1412 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1413 user_struct *vuser = NULL;
1415 sconn->smb1.sessions.last_session_tag = session_tag;
1416 if(session_tag != UID_FIELD_INVALID) {
1417 vuser = get_valid_user_struct(sconn, session_tag);
1418 if (vuser) {
1419 set_current_user_info(
1420 vuser->session_info->unix_info->sanitized_username,
1421 vuser->session_info->unix_info->unix_name,
1422 vuser->session_info->info->domain_name);
1427 /* Does this call need to be run as the connected user? */
1428 if (flags & AS_USER) {
1430 /* Does this call need a valid tree connection? */
1431 if (!conn) {
1433 * Amazingly, the error code depends on the command
1434 * (from Samba4).
1436 if (type == SMBntcreateX) {
1437 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1438 } else {
1439 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1441 return NULL;
1444 if (!change_to_user(conn,session_tag)) {
1445 DEBUG(0, ("Error: Could not change to user. Removing "
1446 "deferred open, mid=%llu.\n",
1447 (unsigned long long)req->mid));
1448 reply_force_doserror(req, ERRSRV, ERRbaduid);
1449 return conn;
1452 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1454 /* Does it need write permission? */
1455 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1456 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1457 return conn;
1460 /* IPC services are limited */
1461 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1462 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1463 return conn;
1465 } else {
1466 /* This call needs to be run as root */
1467 change_to_root_user();
1470 /* load service specific parameters */
1471 if (conn) {
1472 if (req->encrypted) {
1473 conn->encrypted_tid = true;
1474 /* encrypted required from now on. */
1475 conn->encrypt_level = Required;
1476 } else if (ENCRYPTION_REQUIRED(conn)) {
1477 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1478 exit_server_cleanly("encryption required "
1479 "on connection");
1480 return conn;
1484 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1485 (flags & (AS_USER|DO_CHDIR)
1486 ?True:False))) {
1487 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1488 return conn;
1490 conn->num_smb_operations++;
1493 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1494 talloc_tos());
1495 if (raddr == NULL) {
1496 reply_nterror(req, NT_STATUS_NO_MEMORY);
1497 return conn;
1500 /* does this protocol need to be run as guest? */
1501 if ((flags & AS_GUEST)
1502 && (!change_to_guest() ||
1503 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1504 sconn->remote_hostname,
1505 raddr))) {
1506 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1507 return conn;
1510 smb_messages[type].fn(req);
1511 return req->conn;
1514 /****************************************************************************
1515 Construct a reply to the incoming packet.
1516 ****************************************************************************/
1518 static void construct_reply(struct smbd_server_connection *sconn,
1519 char *inbuf, int size, size_t unread_bytes,
1520 uint32_t seqnum, bool encrypted,
1521 struct smb_perfcount_data *deferred_pcd)
1523 connection_struct *conn;
1524 struct smb_request *req;
1526 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1527 smb_panic("could not allocate smb_request");
1530 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1531 encrypted, seqnum)) {
1532 exit_server_cleanly("Invalid SMB request");
1535 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1537 /* we popped this message off the queue - keep original perf data */
1538 if (deferred_pcd)
1539 req->pcd = *deferred_pcd;
1540 else {
1541 SMB_PERFCOUNT_START(&req->pcd);
1542 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1543 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1546 conn = switch_message(req->cmd, req, size);
1548 if (req->unread_bytes) {
1549 /* writeX failed. drain socket. */
1550 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1551 req->unread_bytes) {
1552 smb_panic("failed to drain pending bytes");
1554 req->unread_bytes = 0;
1557 if (req->done) {
1558 TALLOC_FREE(req);
1559 return;
1562 if (req->outbuf == NULL) {
1563 return;
1566 if (CVAL(req->outbuf,0) == 0) {
1567 show_msg((char *)req->outbuf);
1570 if (!srv_send_smb(req->sconn,
1571 (char *)req->outbuf,
1572 true, req->seqnum+1,
1573 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1574 &req->pcd)) {
1575 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1578 TALLOC_FREE(req);
1580 return;
1583 /****************************************************************************
1584 Process an smb from the client
1585 ****************************************************************************/
1586 static void process_smb(struct smbd_server_connection *sconn,
1587 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1588 uint32_t seqnum, bool encrypted,
1589 struct smb_perfcount_data *deferred_pcd)
1591 int msg_type = CVAL(inbuf,0);
1593 DO_PROFILE_INC(smb_count);
1595 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1596 smb_len(inbuf) ) );
1597 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1598 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1600 if (msg_type != NBSSmessage) {
1602 * NetBIOS session request, keepalive, etc.
1604 reply_special(sconn, (char *)inbuf, nread);
1605 goto done;
1608 if (sconn->using_smb2) {
1609 /* At this point we're not really using smb2,
1610 * we make the decision here.. */
1611 if (smbd_is_smb2_header(inbuf, nread)) {
1612 smbd_smb2_first_negprot(sconn, inbuf, nread);
1613 return;
1614 } else if (nread >= smb_size && valid_smb_header(inbuf)
1615 && CVAL(inbuf, smb_com) != 0x72) {
1616 /* This is a non-negprot SMB1 packet.
1617 Disable SMB2 from now on. */
1618 sconn->using_smb2 = false;
1622 show_msg((char *)inbuf);
1624 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1625 encrypted, deferred_pcd);
1626 sconn->trans_num++;
1628 done:
1629 sconn->num_requests++;
1631 /* The timeout_processing function isn't run nearly
1632 often enough to implement 'max log size' without
1633 overrunning the size of the file by many megabytes.
1634 This is especially true if we are running at debug
1635 level 10. Checking every 50 SMBs is a nice
1636 tradeoff of performance vs log file size overrun. */
1638 if ((sconn->num_requests % 50) == 0 &&
1639 need_to_check_log_size()) {
1640 change_to_root_user();
1641 check_log_size();
1645 /****************************************************************************
1646 Return a string containing the function name of a SMB command.
1647 ****************************************************************************/
1649 const char *smb_fn_name(int type)
1651 const char *unknown_name = "SMBunknown";
1653 if (smb_messages[type].name == NULL)
1654 return(unknown_name);
1656 return(smb_messages[type].name);
1659 /****************************************************************************
1660 Helper functions for contruct_reply.
1661 ****************************************************************************/
1663 void add_to_common_flags2(uint32 v)
1665 common_flags2 |= v;
1668 void remove_from_common_flags2(uint32 v)
1670 common_flags2 &= ~v;
1673 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1674 char *outbuf)
1676 srv_set_message(outbuf,0,0,false);
1678 SCVAL(outbuf, smb_com, req->cmd);
1679 SIVAL(outbuf,smb_rcls,0);
1680 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1681 SSVAL(outbuf,smb_flg2,
1682 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1683 common_flags2);
1684 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1686 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1687 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1688 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1689 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1692 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1694 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1698 * How many bytes have we already accumulated up to the current wct field
1699 * offset?
1702 size_t req_wct_ofs(struct smb_request *req)
1704 size_t buf_size;
1706 if (req->chain_outbuf == NULL) {
1707 return smb_wct - 4;
1709 buf_size = talloc_get_size(req->chain_outbuf);
1710 if ((buf_size % 4) != 0) {
1711 buf_size += (4 - (buf_size % 4));
1713 return buf_size - 4;
1717 * Hack around reply_nterror & friends not being aware of chained requests,
1718 * generating illegal (i.e. wct==0) chain replies.
1721 static void fixup_chain_error_packet(struct smb_request *req)
1723 uint8_t *outbuf = req->outbuf;
1724 req->outbuf = NULL;
1725 reply_outbuf(req, 2, 0);
1726 memcpy(req->outbuf, outbuf, smb_wct);
1727 TALLOC_FREE(outbuf);
1728 SCVAL(req->outbuf, smb_vwv0, 0xff);
1732 * @brief Find the smb_cmd offset of the last command pushed
1733 * @param[in] buf The buffer we're building up
1734 * @retval Where can we put our next andx cmd?
1736 * While chaining requests, the "next" request we're looking at needs to put
1737 * its SMB_Command before the data the previous request already built up added
1738 * to the chain. Find the offset to the place where we have to put our cmd.
1741 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1743 uint8_t cmd;
1744 size_t ofs;
1746 cmd = CVAL(buf, smb_com);
1748 SMB_ASSERT(is_andx_req(cmd));
1750 ofs = smb_vwv0;
1752 while (CVAL(buf, ofs) != 0xff) {
1754 if (!is_andx_req(CVAL(buf, ofs))) {
1755 return false;
1759 * ofs is from start of smb header, so add the 4 length
1760 * bytes. The next cmd is right after the wct field.
1762 ofs = SVAL(buf, ofs+2) + 4 + 1;
1764 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1767 *pofs = ofs;
1768 return true;
1772 * @brief Do the smb chaining at a buffer level
1773 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1774 * @param[in] smb_command The command that we want to issue
1775 * @param[in] wct How many words?
1776 * @param[in] vwv The words, already in network order
1777 * @param[in] bytes_alignment How shall we align "bytes"?
1778 * @param[in] num_bytes How many bytes?
1779 * @param[in] bytes The data the request ships
1781 * smb_splice_chain() adds the vwv and bytes to the request already present in
1782 * *poutbuf.
1785 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1786 uint8_t wct, const uint16_t *vwv,
1787 size_t bytes_alignment,
1788 uint32_t num_bytes, const uint8_t *bytes)
1790 uint8_t *outbuf;
1791 size_t old_size, new_size;
1792 size_t ofs;
1793 size_t chain_padding = 0;
1794 size_t bytes_padding = 0;
1795 bool first_request;
1797 old_size = talloc_get_size(*poutbuf);
1800 * old_size == smb_wct means we're pushing the first request in for
1801 * libsmb/
1804 first_request = (old_size == smb_wct);
1806 if (!first_request && ((old_size % 4) != 0)) {
1808 * Align the wct field of subsequent requests to a 4-byte
1809 * boundary
1811 chain_padding = 4 - (old_size % 4);
1815 * After the old request comes the new wct field (1 byte), the vwv's
1816 * and the num_bytes field. After at we might need to align the bytes
1817 * given to us to "bytes_alignment", increasing the num_bytes value.
1820 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1822 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1823 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1826 new_size += bytes_padding + num_bytes;
1828 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1829 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1830 (unsigned)new_size));
1831 return false;
1834 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1835 if (outbuf == NULL) {
1836 DEBUG(0, ("talloc failed\n"));
1837 return false;
1839 *poutbuf = outbuf;
1841 if (first_request) {
1842 SCVAL(outbuf, smb_com, smb_command);
1843 } else {
1844 size_t andx_cmd_ofs;
1846 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1847 DEBUG(1, ("invalid command chain\n"));
1848 *poutbuf = talloc_realloc(
1849 NULL, *poutbuf, uint8_t, old_size);
1850 return false;
1853 if (chain_padding != 0) {
1854 memset(outbuf + old_size, 0, chain_padding);
1855 old_size += chain_padding;
1858 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1859 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1862 ofs = old_size;
1865 * Push the chained request:
1867 * wct field
1870 SCVAL(outbuf, ofs, wct);
1871 ofs += 1;
1874 * vwv array
1877 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1878 ofs += sizeof(uint16_t) * wct;
1881 * bcc (byte count)
1884 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1885 ofs += sizeof(uint16_t);
1888 * padding
1891 if (bytes_padding != 0) {
1892 memset(outbuf + ofs, 0, bytes_padding);
1893 ofs += bytes_padding;
1897 * The bytes field
1900 memcpy(outbuf + ofs, bytes, num_bytes);
1902 return true;
1905 /****************************************************************************
1906 Construct a chained reply and add it to the already made reply
1907 ****************************************************************************/
1909 void chain_reply(struct smb_request *req)
1911 size_t smblen = smb_len(req->inbuf);
1912 size_t already_used, length_needed;
1913 uint8_t chain_cmd;
1914 uint32_t chain_offset; /* uint32_t to avoid overflow */
1916 uint8_t wct;
1917 const uint16_t *vwv;
1918 uint16_t buflen;
1919 const uint8_t *buf;
1921 if (IVAL(req->outbuf, smb_rcls) != 0) {
1922 fixup_chain_error_packet(req);
1926 * Any of the AndX requests and replies have at least a wct of
1927 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1928 * beginning of the SMB header to the next wct field.
1930 * None of the AndX requests put anything valuable in vwv[0] and [1],
1931 * so we can overwrite it here to form the chain.
1934 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1935 if (req->chain_outbuf == NULL) {
1936 req->chain_outbuf = talloc_realloc(
1937 req, req->outbuf, uint8_t,
1938 smb_len(req->outbuf) + 4);
1939 if (req->chain_outbuf == NULL) {
1940 smb_panic("talloc failed");
1943 req->outbuf = NULL;
1944 goto error;
1948 * Here we assume that this is the end of the chain. For that we need
1949 * to set "next command" to 0xff and the offset to 0. If we later find
1950 * more commands in the chain, this will be overwritten again.
1953 SCVAL(req->outbuf, smb_vwv0, 0xff);
1954 SCVAL(req->outbuf, smb_vwv0+1, 0);
1955 SSVAL(req->outbuf, smb_vwv1, 0);
1957 if (req->chain_outbuf == NULL) {
1959 * In req->chain_outbuf we collect all the replies. Start the
1960 * chain by copying in the first reply.
1962 * We do the realloc because later on we depend on
1963 * talloc_get_size to determine the length of
1964 * chain_outbuf. The reply_xxx routines might have
1965 * over-allocated (reply_pipe_read_and_X used to be such an
1966 * example).
1968 req->chain_outbuf = talloc_realloc(
1969 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1970 if (req->chain_outbuf == NULL) {
1971 smb_panic("talloc failed");
1973 req->outbuf = NULL;
1974 } else {
1976 * Update smb headers where subsequent chained commands
1977 * may have updated them.
1979 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1980 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1982 if (!smb_splice_chain(&req->chain_outbuf,
1983 CVAL(req->outbuf, smb_com),
1984 CVAL(req->outbuf, smb_wct),
1985 (uint16_t *)(req->outbuf + smb_vwv),
1986 0, smb_buflen(req->outbuf),
1987 (uint8_t *)smb_buf(req->outbuf))) {
1988 goto error;
1990 TALLOC_FREE(req->outbuf);
1994 * We use the old request's vwv field to grab the next chained command
1995 * and offset into the chained fields.
1998 chain_cmd = CVAL(req->vwv+0, 0);
1999 chain_offset = SVAL(req->vwv+1, 0);
2001 if (chain_cmd == 0xff) {
2003 * End of chain, no more requests from the client. So ship the
2004 * replies.
2006 smb_setlen((char *)(req->chain_outbuf),
2007 talloc_get_size(req->chain_outbuf) - 4);
2009 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2010 true, req->seqnum+1,
2011 IS_CONN_ENCRYPTED(req->conn)
2012 ||req->encrypted,
2013 &req->pcd)) {
2014 exit_server_cleanly("chain_reply: srv_send_smb "
2015 "failed.");
2017 TALLOC_FREE(req->chain_outbuf);
2018 req->done = true;
2019 return;
2022 /* add a new perfcounter for this element of chain */
2023 SMB_PERFCOUNT_ADD(&req->pcd);
2024 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2025 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2028 * Check if the client tries to fool us. The request so far uses the
2029 * space to the end of the byte buffer in the request just
2030 * processed. The chain_offset can't point into that area. If that was
2031 * the case, we could end up with an endless processing of the chain,
2032 * we would always handle the same request.
2035 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2036 if (chain_offset < already_used) {
2037 goto error;
2041 * Next check: Make sure the chain offset does not point beyond the
2042 * overall smb request length.
2045 length_needed = chain_offset+1; /* wct */
2046 if (length_needed > smblen) {
2047 goto error;
2051 * Now comes the pointer magic. Goal here is to set up req->vwv and
2052 * req->buf correctly again to be able to call the subsequent
2053 * switch_message(). The chain offset (the former vwv[1]) points at
2054 * the new wct field.
2057 wct = CVAL(smb_base(req->inbuf), chain_offset);
2060 * Next consistency check: Make the new vwv array fits in the overall
2061 * smb request.
2064 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2065 if (length_needed > smblen) {
2066 goto error;
2068 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2071 * Now grab the new byte buffer....
2074 buflen = SVAL(vwv+wct, 0);
2077 * .. and check that it fits.
2080 length_needed += buflen;
2081 if (length_needed > smblen) {
2082 goto error;
2084 buf = (const uint8_t *)(vwv+wct+1);
2086 req->cmd = chain_cmd;
2087 req->wct = wct;
2088 req->vwv = discard_const_p(uint16_t, vwv);
2089 req->buflen = buflen;
2090 req->buf = buf;
2092 switch_message(chain_cmd, req, smblen);
2094 if (req->outbuf == NULL) {
2096 * This happens if the chained command has suspended itself or
2097 * if it has called srv_send_smb() itself.
2099 return;
2103 * We end up here if the chained command was not itself chained or
2104 * suspended, but for example a close() command. We now need to splice
2105 * the chained commands' outbuf into the already built up chain_outbuf
2106 * and ship the result.
2108 goto done;
2110 error:
2112 * We end up here if there's any error in the chain syntax. Report a
2113 * DOS error, just like Windows does.
2115 reply_force_doserror(req, ERRSRV, ERRerror);
2116 fixup_chain_error_packet(req);
2118 done:
2120 * This scary statement intends to set the
2121 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2122 * to the value req->outbuf carries
2124 SSVAL(req->chain_outbuf, smb_flg2,
2125 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2126 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2129 * Transfer the error codes from the subrequest to the main one
2131 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2132 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2134 if (!smb_splice_chain(&req->chain_outbuf,
2135 CVAL(req->outbuf, smb_com),
2136 CVAL(req->outbuf, smb_wct),
2137 (uint16_t *)(req->outbuf + smb_vwv),
2138 0, smb_buflen(req->outbuf),
2139 (uint8_t *)smb_buf(req->outbuf))) {
2140 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2142 TALLOC_FREE(req->outbuf);
2144 smb_setlen((char *)(req->chain_outbuf),
2145 talloc_get_size(req->chain_outbuf) - 4);
2147 show_msg((char *)(req->chain_outbuf));
2149 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2150 true, req->seqnum+1,
2151 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2152 &req->pcd)) {
2153 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2155 TALLOC_FREE(req->chain_outbuf);
2156 req->done = true;
2159 /****************************************************************************
2160 Check if services need reloading.
2161 ****************************************************************************/
2163 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2166 if (last_smb_conf_reload_time == 0) {
2167 last_smb_conf_reload_time = t;
2170 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2171 reload_services(sconn->msg_ctx, sconn->sock, True);
2172 last_smb_conf_reload_time = t;
2176 static bool fd_is_readable(int fd)
2178 int ret, revents;
2180 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2182 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2186 static void smbd_server_connection_write_handler(
2187 struct smbd_server_connection *sconn)
2189 /* TODO: make write nonblocking */
2192 static void smbd_server_connection_read_handler(
2193 struct smbd_server_connection *sconn, int fd)
2195 uint8_t *inbuf = NULL;
2196 size_t inbuf_len = 0;
2197 size_t unread_bytes = 0;
2198 bool encrypted = false;
2199 TALLOC_CTX *mem_ctx = talloc_tos();
2200 NTSTATUS status;
2201 uint32_t seqnum;
2203 bool from_client = (sconn->sock == fd);
2205 if (from_client) {
2206 smbd_lock_socket(sconn);
2208 if (lp_async_smb_echo_handler()) {
2210 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2212 * This is the super-ugly hack to
2213 * prefer the packets forwarded by the
2214 * echo handler over the ones by the
2215 * client directly
2217 fd = sconn->smb1.echo_handler.trusted_fd;
2218 } else if (!fd_is_readable(fd)) {
2219 DEBUG(10,("the echo listener was faster\n"));
2220 smbd_unlock_socket(sconn);
2221 return;
2225 /* TODO: make this completely nonblocking */
2226 status = receive_smb_talloc(mem_ctx, sconn, fd,
2227 (char **)(void *)&inbuf,
2228 0, /* timeout */
2229 &unread_bytes,
2230 &encrypted,
2231 &inbuf_len, &seqnum,
2232 false /* trusted channel */);
2233 smbd_unlock_socket(sconn);
2234 } else {
2235 /* TODO: make this completely nonblocking */
2236 status = receive_smb_talloc(mem_ctx, sconn, fd,
2237 (char **)(void *)&inbuf,
2238 0, /* timeout */
2239 &unread_bytes,
2240 &encrypted,
2241 &inbuf_len, &seqnum,
2242 true /* trusted channel */);
2245 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2246 goto process;
2248 if (NT_STATUS_IS_ERR(status)) {
2249 exit_server_cleanly("failed to receive smb request");
2251 if (!NT_STATUS_IS_OK(status)) {
2252 return;
2255 process:
2256 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2257 seqnum, encrypted, NULL);
2260 static void smbd_server_connection_handler(struct event_context *ev,
2261 struct fd_event *fde,
2262 uint16_t flags,
2263 void *private_data)
2265 struct smbd_server_connection *conn = talloc_get_type(private_data,
2266 struct smbd_server_connection);
2268 if (flags & EVENT_FD_WRITE) {
2269 smbd_server_connection_write_handler(conn);
2270 return;
2272 if (flags & EVENT_FD_READ) {
2273 smbd_server_connection_read_handler(conn, conn->sock);
2274 return;
2278 static void smbd_server_echo_handler(struct event_context *ev,
2279 struct fd_event *fde,
2280 uint16_t flags,
2281 void *private_data)
2283 struct smbd_server_connection *conn = talloc_get_type(private_data,
2284 struct smbd_server_connection);
2286 if (flags & EVENT_FD_WRITE) {
2287 smbd_server_connection_write_handler(conn);
2288 return;
2290 if (flags & EVENT_FD_READ) {
2291 smbd_server_connection_read_handler(
2292 conn, conn->smb1.echo_handler.trusted_fd);
2293 return;
2297 #ifdef CLUSTER_SUPPORT
2298 /****************************************************************************
2299 received when we should release a specific IP
2300 ****************************************************************************/
2301 static void release_ip(const char *ip, void *priv)
2303 const char *addr = (const char *)priv;
2304 const char *p = addr;
2306 if (strncmp("::ffff:", addr, 7) == 0) {
2307 p = addr + 7;
2310 DEBUG(10, ("Got release IP message for %s, "
2311 "our address is %s\n", ip, p));
2313 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2314 /* we can't afford to do a clean exit - that involves
2315 database writes, which would potentially mean we
2316 are still running after the failover has finished -
2317 we have to get rid of this process ID straight
2318 away */
2319 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2320 ip));
2321 /* note we must exit with non-zero status so the unclean handler gets
2322 called in the parent, so that the brl database is tickled */
2323 _exit(1);
2327 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2328 struct sockaddr_storage *client)
2330 socklen_t length;
2331 length = sizeof(*server);
2332 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2333 return -1;
2335 length = sizeof(*client);
2336 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2337 return -1;
2339 return 0;
2341 #endif
2344 * Send keepalive packets to our client
2346 static bool keepalive_fn(const struct timeval *now, void *private_data)
2348 struct smbd_server_connection *sconn = smbd_server_conn;
2349 bool ret;
2351 if (sconn->using_smb2) {
2352 /* Don't do keepalives on an SMB2 connection. */
2353 return false;
2356 smbd_lock_socket(smbd_server_conn);
2357 ret = send_keepalive(sconn->sock);
2358 smbd_unlock_socket(smbd_server_conn);
2360 if (!ret) {
2361 char addr[INET6_ADDRSTRLEN];
2363 * Try and give an error message saying what
2364 * client failed.
2366 DEBUG(0, ("send_keepalive failed for client %s. "
2367 "Error %s - exiting\n",
2368 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2369 strerror(errno)));
2370 return False;
2372 return True;
2376 * Do the recurring check if we're idle
2378 static bool deadtime_fn(const struct timeval *now, void *private_data)
2380 struct smbd_server_connection *sconn =
2381 (struct smbd_server_connection *)private_data;
2383 if ((conn_num_open(sconn) == 0)
2384 || (conn_idle_all(sconn, now->tv_sec))) {
2385 DEBUG( 2, ( "Closing idle connection\n" ) );
2386 messaging_send(sconn->msg_ctx,
2387 messaging_server_id(sconn->msg_ctx),
2388 MSG_SHUTDOWN, &data_blob_null);
2389 return False;
2392 return True;
2396 * Do the recurring log file and smb.conf reload checks.
2399 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2401 struct smbd_server_connection *sconn = talloc_get_type_abort(
2402 private_data, struct smbd_server_connection);
2404 DEBUG(5, ("housekeeping\n"));
2406 change_to_root_user();
2408 /* update printer queue caches if necessary */
2409 update_monitored_printq_cache(sconn->msg_ctx);
2411 /* check if we need to reload services */
2412 check_reload(sconn, time_mono(NULL));
2414 /* Change machine password if neccessary. */
2415 attempt_machine_password_change();
2418 * Force a log file check.
2420 force_check_log_size();
2421 check_log_size();
2422 return true;
2425 static int create_unlink_tmp(const char *dir)
2427 char *fname;
2428 int fd;
2430 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2431 if (fname == NULL) {
2432 errno = ENOMEM;
2433 return -1;
2435 fd = mkstemp(fname);
2436 if (fd == -1) {
2437 TALLOC_FREE(fname);
2438 return -1;
2440 if (unlink(fname) == -1) {
2441 int sys_errno = errno;
2442 close(fd);
2443 TALLOC_FREE(fname);
2444 errno = sys_errno;
2445 return -1;
2447 TALLOC_FREE(fname);
2448 return fd;
2452 * Read an smb packet in the echo handler child, giving the parent
2453 * smbd one second to react once the socket becomes readable.
2456 struct smbd_echo_read_state {
2457 struct tevent_context *ev;
2458 struct smbd_server_connection *sconn;
2460 char *buf;
2461 size_t buflen;
2462 uint32_t seqnum;
2465 static void smbd_echo_read_readable(struct tevent_req *subreq);
2466 static void smbd_echo_read_waited(struct tevent_req *subreq);
2468 static struct tevent_req *smbd_echo_read_send(
2469 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2470 struct smbd_server_connection *sconn)
2472 struct tevent_req *req, *subreq;
2473 struct smbd_echo_read_state *state;
2475 req = tevent_req_create(mem_ctx, &state,
2476 struct smbd_echo_read_state);
2477 if (req == NULL) {
2478 return NULL;
2480 state->ev = ev;
2481 state->sconn = sconn;
2483 subreq = wait_for_read_send(state, ev, sconn->sock);
2484 if (tevent_req_nomem(subreq, req)) {
2485 return tevent_req_post(req, ev);
2487 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2488 return req;
2491 static void smbd_echo_read_readable(struct tevent_req *subreq)
2493 struct tevent_req *req = tevent_req_callback_data(
2494 subreq, struct tevent_req);
2495 struct smbd_echo_read_state *state = tevent_req_data(
2496 req, struct smbd_echo_read_state);
2497 bool ok;
2498 int err;
2500 ok = wait_for_read_recv(subreq, &err);
2501 TALLOC_FREE(subreq);
2502 if (!ok) {
2503 tevent_req_nterror(req, map_nt_error_from_unix(err));
2504 return;
2508 * Give the parent smbd one second to step in
2511 subreq = tevent_wakeup_send(
2512 state, state->ev, timeval_current_ofs(1, 0));
2513 if (tevent_req_nomem(subreq, req)) {
2514 return;
2516 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2519 static void smbd_echo_read_waited(struct tevent_req *subreq)
2521 struct tevent_req *req = tevent_req_callback_data(
2522 subreq, struct tevent_req);
2523 struct smbd_echo_read_state *state = tevent_req_data(
2524 req, struct smbd_echo_read_state);
2525 struct smbd_server_connection *sconn = state->sconn;
2526 bool ok;
2527 NTSTATUS status;
2528 size_t unread = 0;
2529 bool encrypted;
2531 ok = tevent_wakeup_recv(subreq);
2532 TALLOC_FREE(subreq);
2533 if (!ok) {
2534 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2535 return;
2538 ok = smbd_lock_socket_internal(sconn);
2539 if (!ok) {
2540 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2541 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2542 return;
2545 if (!fd_is_readable(sconn->sock)) {
2546 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2547 (int)sys_getpid()));
2549 ok = smbd_unlock_socket_internal(sconn);
2550 if (!ok) {
2551 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2552 DEBUG(1, ("%s: failed to unlock socket\n",
2553 __location__));
2554 return;
2557 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2558 if (tevent_req_nomem(subreq, req)) {
2559 return;
2561 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2562 return;
2565 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2566 0 /* timeout */,
2567 &unread,
2568 &encrypted,
2569 &state->buflen,
2570 &state->seqnum,
2571 false /* trusted_channel*/);
2573 if (tevent_req_nterror(req, status)) {
2574 tevent_req_nterror(req, status);
2575 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2576 (int)sys_getpid(), nt_errstr(status)));
2577 return;
2580 ok = smbd_unlock_socket_internal(sconn);
2581 if (!ok) {
2582 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2583 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2584 return;
2586 tevent_req_done(req);
2589 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2590 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2592 struct smbd_echo_read_state *state = tevent_req_data(
2593 req, struct smbd_echo_read_state);
2594 NTSTATUS status;
2596 if (tevent_req_is_nterror(req, &status)) {
2597 return status;
2599 *pbuf = talloc_move(mem_ctx, &state->buf);
2600 *pbuflen = state->buflen;
2601 *pseqnum = state->seqnum;
2602 return NT_STATUS_OK;
2605 struct smbd_echo_state {
2606 struct tevent_context *ev;
2607 struct iovec *pending;
2608 struct smbd_server_connection *sconn;
2609 int parent_pipe;
2611 struct tevent_fd *parent_fde;
2613 struct tevent_req *write_req;
2616 static void smbd_echo_writer_done(struct tevent_req *req);
2618 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2620 int num_pending;
2622 if (state->write_req != NULL) {
2623 return;
2626 num_pending = talloc_array_length(state->pending);
2627 if (num_pending == 0) {
2628 return;
2631 state->write_req = writev_send(state, state->ev, NULL,
2632 state->parent_pipe, false,
2633 state->pending, num_pending);
2634 if (state->write_req == NULL) {
2635 DEBUG(1, ("writev_send failed\n"));
2636 exit(1);
2639 talloc_steal(state->write_req, state->pending);
2640 state->pending = NULL;
2642 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2643 state);
2646 static void smbd_echo_writer_done(struct tevent_req *req)
2648 struct smbd_echo_state *state = tevent_req_callback_data(
2649 req, struct smbd_echo_state);
2650 ssize_t written;
2651 int err;
2653 written = writev_recv(req, &err);
2654 TALLOC_FREE(req);
2655 state->write_req = NULL;
2656 if (written == -1) {
2657 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2658 exit(1);
2660 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2661 smbd_echo_activate_writer(state);
2664 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2665 uint32_t seqnum)
2667 struct smb_request req;
2668 uint16_t num_replies;
2669 size_t out_len;
2670 char *outbuf;
2671 bool ok;
2673 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2674 DEBUG(10, ("Got netbios keepalive\n"));
2676 * Just swallow it
2678 return true;
2681 if (inbuf_len < smb_size) {
2682 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2683 return false;
2685 if (!valid_smb_header(inbuf)) {
2686 DEBUG(10, ("Got invalid SMB header\n"));
2687 return false;
2690 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2691 seqnum)) {
2692 return false;
2694 req.inbuf = inbuf;
2696 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2697 smb_messages[req.cmd].name
2698 ? smb_messages[req.cmd].name : "unknown"));
2700 if (req.cmd != SMBecho) {
2701 return false;
2703 if (req.wct < 1) {
2704 return false;
2707 num_replies = SVAL(req.vwv+0, 0);
2708 if (num_replies != 1) {
2709 /* Not a Windows "Hey, you're still there?" request */
2710 return false;
2713 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2714 1, req.buflen)) {
2715 DEBUG(10, ("create_outbuf failed\n"));
2716 return false;
2718 req.outbuf = (uint8_t *)outbuf;
2720 SSVAL(req.outbuf, smb_vwv0, num_replies);
2722 if (req.buflen > 0) {
2723 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2726 out_len = smb_len(req.outbuf) + 4;
2728 ok = srv_send_smb(req.sconn,
2729 (char *)outbuf,
2730 true, seqnum+1,
2731 false, &req.pcd);
2732 TALLOC_FREE(outbuf);
2733 if (!ok) {
2734 exit(1);
2737 return true;
2740 static void smbd_echo_exit(struct tevent_context *ev,
2741 struct tevent_fd *fde, uint16_t flags,
2742 void *private_data)
2744 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2745 exit(0);
2748 static void smbd_echo_got_packet(struct tevent_req *req);
2750 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2751 int parent_pipe)
2753 struct smbd_echo_state *state;
2754 struct tevent_req *read_req;
2756 state = talloc_zero(sconn, struct smbd_echo_state);
2757 if (state == NULL) {
2758 DEBUG(1, ("talloc failed\n"));
2759 return;
2761 state->sconn = sconn;
2762 state->parent_pipe = parent_pipe;
2763 state->ev = s3_tevent_context_init(state);
2764 if (state->ev == NULL) {
2765 DEBUG(1, ("tevent_context_init failed\n"));
2766 TALLOC_FREE(state);
2767 return;
2769 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2770 TEVENT_FD_READ, smbd_echo_exit,
2771 state);
2772 if (state->parent_fde == NULL) {
2773 DEBUG(1, ("tevent_add_fd failed\n"));
2774 TALLOC_FREE(state);
2775 return;
2778 read_req = smbd_echo_read_send(state, state->ev, sconn);
2779 if (read_req == NULL) {
2780 DEBUG(1, ("smbd_echo_read_send failed\n"));
2781 TALLOC_FREE(state);
2782 return;
2784 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2786 while (true) {
2787 if (tevent_loop_once(state->ev) == -1) {
2788 DEBUG(1, ("tevent_loop_once failed: %s\n",
2789 strerror(errno)));
2790 break;
2793 TALLOC_FREE(state);
2796 static void smbd_echo_got_packet(struct tevent_req *req)
2798 struct smbd_echo_state *state = tevent_req_callback_data(
2799 req, struct smbd_echo_state);
2800 NTSTATUS status;
2801 char *buf = NULL;
2802 size_t buflen = 0;
2803 uint32_t seqnum = 0;
2804 bool reply;
2806 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2807 TALLOC_FREE(req);
2808 if (!NT_STATUS_IS_OK(status)) {
2809 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2810 nt_errstr(status)));
2811 exit(1);
2814 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2815 if (!reply) {
2816 size_t num_pending;
2817 struct iovec *tmp;
2818 struct iovec *iov;
2820 num_pending = talloc_array_length(state->pending);
2821 tmp = talloc_realloc(state, state->pending, struct iovec,
2822 num_pending+1);
2823 if (tmp == NULL) {
2824 DEBUG(1, ("talloc_realloc failed\n"));
2825 exit(1);
2827 state->pending = tmp;
2829 if (buflen >= smb_size) {
2831 * place the seqnum in the packet so that the main process
2832 * can reply with signing
2834 SIVAL(buf, smb_ss_field, seqnum);
2835 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2838 iov = &state->pending[num_pending];
2839 iov->iov_base = buf;
2840 iov->iov_len = buflen;
2842 DEBUG(10,("echo_handler[%d]: forward to main\n",
2843 (int)sys_getpid()));
2844 smbd_echo_activate_writer(state);
2847 req = smbd_echo_read_send(state, state->ev, state->sconn);
2848 if (req == NULL) {
2849 DEBUG(1, ("smbd_echo_read_send failed\n"));
2850 exit(1);
2852 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2857 * Handle SMBecho requests in a forked child process
2859 bool fork_echo_handler(struct smbd_server_connection *sconn)
2861 int listener_pipe[2];
2862 int res;
2863 pid_t child;
2865 res = pipe(listener_pipe);
2866 if (res == -1) {
2867 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2868 return false;
2870 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2871 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2872 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2873 goto fail;
2876 child = sys_fork();
2877 if (child == 0) {
2878 NTSTATUS status;
2880 close(listener_pipe[0]);
2881 set_blocking(listener_pipe[1], false);
2883 status = reinit_after_fork(sconn->msg_ctx,
2884 server_event_context(),
2885 procid_self(), false);
2886 if (!NT_STATUS_IS_OK(status)) {
2887 DEBUG(1, ("reinit_after_fork failed: %s\n",
2888 nt_errstr(status)));
2889 exit(1);
2891 smbd_echo_loop(sconn, listener_pipe[1]);
2892 exit(0);
2894 close(listener_pipe[1]);
2895 listener_pipe[1] = -1;
2896 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2898 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2901 * Without smb signing this is the same as the normal smbd
2902 * listener. This needs to change once signing comes in.
2904 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2905 sconn,
2906 sconn->smb1.echo_handler.trusted_fd,
2907 EVENT_FD_READ,
2908 smbd_server_echo_handler,
2909 sconn);
2910 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2911 DEBUG(1, ("event_add_fd failed\n"));
2912 goto fail;
2915 return true;
2917 fail:
2918 if (listener_pipe[0] != -1) {
2919 close(listener_pipe[0]);
2921 if (listener_pipe[1] != -1) {
2922 close(listener_pipe[1]);
2924 sconn->smb1.echo_handler.trusted_fd = -1;
2925 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2926 close(sconn->smb1.echo_handler.socket_lock_fd);
2928 sconn->smb1.echo_handler.trusted_fd = -1;
2929 sconn->smb1.echo_handler.socket_lock_fd = -1;
2930 return false;
2933 #if CLUSTER_SUPPORT
2935 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2936 struct sockaddr_storage *srv,
2937 struct sockaddr_storage *clnt)
2939 struct ctdbd_connection *cconn;
2940 char tmp_addr[INET6_ADDRSTRLEN];
2941 char *addr;
2943 cconn = messaging_ctdbd_connection();
2944 if (cconn == NULL) {
2945 return NT_STATUS_NO_MEMORY;
2948 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2949 addr = talloc_strdup(cconn, tmp_addr);
2950 if (addr == NULL) {
2951 return NT_STATUS_NO_MEMORY;
2953 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2956 #endif
2958 /****************************************************************************
2959 Process commands from the client
2960 ****************************************************************************/
2962 void smbd_process(struct tevent_context *ev_ctx,
2963 struct smbd_server_connection *sconn)
2965 TALLOC_CTX *frame = talloc_stackframe();
2966 struct sockaddr_storage ss;
2967 struct sockaddr *sa = NULL;
2968 socklen_t sa_socklen;
2969 struct tsocket_address *local_address = NULL;
2970 struct tsocket_address *remote_address = NULL;
2971 const char *remaddr = NULL;
2972 char *rhost;
2973 int ret;
2975 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2977 * We're not making the decision here,
2978 * we're just allowing the client
2979 * to decide between SMB1 and SMB2
2980 * with the first negprot
2981 * packet.
2983 sconn->using_smb2 = true;
2986 /* Ensure child is set to blocking mode */
2987 set_blocking(sconn->sock,True);
2989 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2990 set_socket_options(sconn->sock, lp_socket_options());
2992 sa = (struct sockaddr *)(void *)&ss;
2993 sa_socklen = sizeof(ss);
2994 ret = getpeername(sconn->sock, sa, &sa_socklen);
2995 if (ret != 0) {
2996 int level = (errno == ENOTCONN)?2:0;
2997 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2998 exit_server_cleanly("getpeername() failed.\n");
3000 ret = tsocket_address_bsd_from_sockaddr(sconn,
3001 sa, sa_socklen,
3002 &remote_address);
3003 if (ret != 0) {
3004 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3005 __location__, strerror(errno)));
3006 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3009 sa = (struct sockaddr *)(void *)&ss;
3010 sa_socklen = sizeof(ss);
3011 ret = getsockname(sconn->sock, sa, &sa_socklen);
3012 if (ret != 0) {
3013 int level = (errno == ENOTCONN)?2:0;
3014 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3015 exit_server_cleanly("getsockname() failed.\n");
3017 ret = tsocket_address_bsd_from_sockaddr(sconn,
3018 sa, sa_socklen,
3019 &local_address);
3020 if (ret != 0) {
3021 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3022 __location__, strerror(errno)));
3023 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3026 sconn->local_address = local_address;
3027 sconn->remote_address = remote_address;
3029 if (tsocket_address_is_inet(remote_address, "ip")) {
3030 remaddr = tsocket_address_inet_addr_string(
3031 sconn->remote_address,
3032 talloc_tos());
3033 if (remaddr == NULL) {
3034 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3035 __location__, strerror(errno)));
3036 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3038 } else {
3039 remaddr = "0.0.0.0";
3042 /* this is needed so that we get decent entries
3043 in smbstatus for port 445 connects */
3044 set_remote_machine_name(remaddr, false);
3045 reload_services(sconn->msg_ctx, sconn->sock, true);
3048 * Before the first packet, check the global hosts allow/ hosts deny
3049 * parameters before doing any parsing of packets passed to us by the
3050 * client. This prevents attacks on our parsing code from hosts not in
3051 * the hosts allow list.
3054 ret = get_remote_hostname(remote_address,
3055 &rhost,
3056 talloc_tos());
3057 if (ret < 0) {
3058 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3059 __location__, strerror(errno)));
3060 exit_server_cleanly("get_remote_hostname failed.\n");
3062 if (strequal(rhost, "UNKNOWN")) {
3063 rhost = talloc_strdup(talloc_tos(), remaddr);
3065 sconn->remote_hostname = talloc_move(sconn, &rhost);
3067 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3068 sconn->remote_hostname,
3069 remaddr)) {
3071 * send a negative session response "not listening on calling
3072 * name"
3074 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3075 DEBUG( 1, ("Connection denied from %s to %s\n",
3076 tsocket_address_string(remote_address, talloc_tos()),
3077 tsocket_address_string(local_address, talloc_tos())));
3078 (void)srv_send_smb(sconn,(char *)buf, false,
3079 0, false, NULL);
3080 exit_server_cleanly("connection denied");
3083 DEBUG(10, ("Connection allowed from %s to %s\n",
3084 tsocket_address_string(remote_address, talloc_tos()),
3085 tsocket_address_string(local_address, talloc_tos())));
3087 init_modules();
3089 smb_perfcount_init();
3091 if (!init_account_policy()) {
3092 exit_server("Could not open account policy tdb.\n");
3095 if (*lp_rootdir()) {
3096 if (chroot(lp_rootdir()) != 0) {
3097 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3098 exit_server("Failed to chroot()");
3100 if (chdir("/") == -1) {
3101 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3102 exit_server("Failed to chroot()");
3104 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3107 if (!srv_init_signing(sconn)) {
3108 exit_server("Failed to init smb_signing");
3111 /* Setup oplocks */
3112 if (!init_oplocks(sconn->msg_ctx))
3113 exit_server("Failed to init oplocks");
3115 /* register our message handlers */
3116 messaging_register(sconn->msg_ctx, NULL,
3117 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3118 messaging_register(sconn->msg_ctx, NULL,
3119 MSG_SMB_CLOSE_FILE, msg_close_file);
3122 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3123 * MSGs to all child processes
3125 messaging_deregister(sconn->msg_ctx,
3126 MSG_DEBUG, NULL);
3127 messaging_register(sconn->msg_ctx, NULL,
3128 MSG_DEBUG, debug_message);
3130 if ((lp_keepalive() != 0)
3131 && !(event_add_idle(ev_ctx, NULL,
3132 timeval_set(lp_keepalive(), 0),
3133 "keepalive", keepalive_fn,
3134 NULL))) {
3135 DEBUG(0, ("Could not add keepalive event\n"));
3136 exit(1);
3139 if (!(event_add_idle(ev_ctx, NULL,
3140 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3141 "deadtime", deadtime_fn, sconn))) {
3142 DEBUG(0, ("Could not add deadtime event\n"));
3143 exit(1);
3146 if (!(event_add_idle(ev_ctx, NULL,
3147 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3148 "housekeeping", housekeeping_fn, sconn))) {
3149 DEBUG(0, ("Could not add housekeeping event\n"));
3150 exit(1);
3153 #ifdef CLUSTER_SUPPORT
3155 if (lp_clustering()) {
3157 * We need to tell ctdb about our client's TCP
3158 * connection, so that for failover ctdbd can send
3159 * tickle acks, triggering a reconnection by the
3160 * client.
3163 struct sockaddr_storage srv, clnt;
3165 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3166 NTSTATUS status;
3167 status = smbd_register_ips(sconn, &srv, &clnt);
3168 if (!NT_STATUS_IS_OK(status)) {
3169 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3170 nt_errstr(status)));
3172 } else
3174 DEBUG(0,("Unable to get tcp info for "
3175 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3176 strerror(errno)));
3180 #endif
3182 sconn->nbt.got_session = false;
3184 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3186 sconn->smb1.sessions.done_sesssetup = false;
3187 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3188 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3189 /* users from session setup */
3190 sconn->smb1.sessions.session_userlist = NULL;
3191 /* workgroup from session setup. */
3192 sconn->smb1.sessions.session_workgroup = NULL;
3193 /* this holds info on user ids that are already validated for this VC */
3194 sconn->smb1.sessions.validated_users = NULL;
3195 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3196 sconn->smb1.sessions.num_validated_vuids = 0;
3198 conn_init(sconn);
3199 if (!init_dptrs(sconn)) {
3200 exit_server("init_dptrs() failed");
3203 sconn->smb1.fde = event_add_fd(ev_ctx,
3204 sconn,
3205 sconn->sock,
3206 EVENT_FD_READ,
3207 smbd_server_connection_handler,
3208 sconn);
3209 if (!sconn->smb1.fde) {
3210 exit_server("failed to create smbd_server_connection fde");
3213 TALLOC_FREE(frame);
3215 while (True) {
3216 NTSTATUS status;
3218 frame = talloc_stackframe_pool(8192);
3220 errno = 0;
3222 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3223 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3224 !NT_STATUS_IS_OK(status)) {
3225 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3226 " exiting\n", nt_errstr(status)));
3227 break;
3230 TALLOC_FREE(frame);
3233 exit_server_cleanly(NULL);
3236 bool req_is_in_chain(struct smb_request *req)
3238 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3240 * We're right now handling a subsequent request, so we must
3241 * be in a chain
3243 return true;
3246 if (!is_andx_req(req->cmd)) {
3247 return false;
3250 if (req->wct < 2) {
3252 * Okay, an illegal request, but definitely not chained :-)
3254 return false;
3257 return (CVAL(req->vwv+0, 0) != 0xFF);