socket_wrapper: fix compiler warnings
[Samba/gbeck.git] / source3 / smbd / process.c
blob48d317bba294fc11e60288ff2897e5d5098948a4
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 "smbd/globals.h"
23 #include "librpc/gen_ndr/netlogon.h"
24 #include "librpc/gen_ndr/messaging.h"
25 #include "../lib/async_req/async_sock.h"
26 #include "ctdbd_conn.h"
27 #include "../lib/util/select.h"
28 #include "printing/pcap.h"
29 #include "system/select.h"
31 extern bool global_machine_password_needs_changing;
33 static void construct_reply_common(struct smb_request *req, const char *inbuf,
34 char *outbuf);
35 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
37 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
39 bool ok;
41 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
42 return true;
45 sconn->smb1.echo_handler.ref_count++;
47 if (sconn->smb1.echo_handler.ref_count > 1) {
48 return true;
51 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
53 do {
54 ok = fcntl_lock(
55 sconn->smb1.echo_handler.socket_lock_fd,
56 SMB_F_SETLKW, 0, 0, F_WRLCK);
57 } while (!ok && (errno == EINTR));
59 if (!ok) {
60 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
61 return false;
64 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
66 return true;
69 void smbd_lock_socket(struct smbd_server_connection *sconn)
71 if (!smbd_lock_socket_internal(sconn)) {
72 exit_server_cleanly("failed to lock socket");
76 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
78 bool ok;
80 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
81 return true;
84 sconn->smb1.echo_handler.ref_count--;
86 if (sconn->smb1.echo_handler.ref_count > 0) {
87 return true;
90 do {
91 ok = fcntl_lock(
92 sconn->smb1.echo_handler.socket_lock_fd,
93 SMB_F_SETLKW, 0, 0, F_UNLCK);
94 } while (!ok && (errno == EINTR));
96 if (!ok) {
97 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
98 return false;
101 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
103 return true;
106 void smbd_unlock_socket(struct smbd_server_connection *sconn)
108 if (!smbd_unlock_socket_internal(sconn)) {
109 exit_server_cleanly("failed to unlock socket");
113 /* Accessor function for smb_read_error for smbd functions. */
115 /****************************************************************************
116 Send an smb to a fd.
117 ****************************************************************************/
119 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
120 bool do_signing, uint32_t seqnum,
121 bool do_encrypt,
122 struct smb_perfcount_data *pcd)
124 size_t len = 0;
125 size_t nwritten=0;
126 ssize_t ret;
127 char *buf_out = buffer;
129 smbd_lock_socket(sconn);
131 if (do_signing) {
132 /* Sign the outgoing packet if required. */
133 srv_calculate_sign_mac(sconn, buf_out, seqnum);
136 if (do_encrypt) {
137 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
138 if (!NT_STATUS_IS_OK(status)) {
139 DEBUG(0, ("send_smb: SMB encryption failed "
140 "on outgoing packet! Error %s\n",
141 nt_errstr(status) ));
142 goto out;
146 len = smb_len(buf_out) + 4;
148 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
149 if (ret <= 0) {
151 char addr[INET6_ADDRSTRLEN];
153 * Try and give an error message saying what
154 * client failed.
156 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
157 (int)sys_getpid(), (int)len,
158 get_peer_addr(sconn->sock, addr, sizeof(addr)),
159 (int)ret, strerror(errno) ));
161 srv_free_enc_buffer(buf_out);
162 goto out;
165 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
166 srv_free_enc_buffer(buf_out);
167 out:
168 SMB_PERFCOUNT_END(pcd);
170 smbd_unlock_socket(sconn);
171 return true;
174 /*******************************************************************
175 Setup the word count and byte count for a smb message.
176 ********************************************************************/
178 int srv_set_message(char *buf,
179 int num_words,
180 int num_bytes,
181 bool zero)
183 if (zero && (num_words || num_bytes)) {
184 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
186 SCVAL(buf,smb_wct,num_words);
187 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
188 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
189 return (smb_size + num_words*2 + num_bytes);
192 static bool valid_smb_header(const uint8_t *inbuf)
194 if (is_encrypted_packet(inbuf)) {
195 return true;
198 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
199 * but it just looks weird to call strncmp for this one.
201 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
204 /* Socket functions for smbd packet processing. */
206 static bool valid_packet_size(size_t len)
209 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
210 * of header. Don't print the error if this fits.... JRA.
213 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
214 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
215 (unsigned long)len));
216 return false;
218 return true;
221 static NTSTATUS read_packet_remainder(int fd, char *buffer,
222 unsigned int timeout, ssize_t len)
224 NTSTATUS status;
226 if (len <= 0) {
227 return NT_STATUS_OK;
230 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
231 if (!NT_STATUS_IS_OK(status)) {
232 char addr[INET6_ADDRSTRLEN];
233 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
234 "error = %s.\n",
235 get_peer_addr(fd, addr, sizeof(addr)),
236 nt_errstr(status)));
238 return status;
241 /****************************************************************************
242 Attempt a zerocopy writeX read. We know here that len > smb_size-4
243 ****************************************************************************/
246 * Unfortunately, earlier versions of smbclient/libsmbclient
247 * don't send this "standard" writeX header. I've fixed this
248 * for 3.2 but we'll use the old method with earlier versions.
249 * Windows and CIFSFS at least use this standard size. Not
250 * sure about MacOSX.
253 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
254 (2*14) + /* word count (including bcc) */ \
255 1 /* pad byte */)
257 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
258 const char lenbuf[4],
259 struct smbd_server_connection *sconn,
260 char **buffer,
261 unsigned int timeout,
262 size_t *p_unread,
263 size_t *len_ret)
265 /* Size of a WRITEX call (+4 byte len). */
266 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
267 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
268 ssize_t toread;
269 NTSTATUS status;
271 memcpy(writeX_header, lenbuf, 4);
273 status = read_fd_with_timeout(
274 sconn->sock, writeX_header + 4,
275 STANDARD_WRITE_AND_X_HEADER_SIZE,
276 STANDARD_WRITE_AND_X_HEADER_SIZE,
277 timeout, NULL);
279 if (!NT_STATUS_IS_OK(status)) {
280 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
281 "error = %s.\n", sconn->client_id.addr,
282 nt_errstr(status)));
283 return status;
287 * Ok - now try and see if this is a possible
288 * valid writeX call.
291 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
293 * If the data offset is beyond what
294 * we've read, drain the extra bytes.
296 uint16_t doff = SVAL(writeX_header,smb_vwv11);
297 ssize_t newlen;
299 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
300 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
301 if (drain_socket(sconn->sock, drain) != drain) {
302 smb_panic("receive_smb_raw_talloc_partial_read:"
303 " failed to drain pending bytes");
305 } else {
306 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
309 /* Spoof down the length and null out the bcc. */
310 set_message_bcc(writeX_header, 0);
311 newlen = smb_len(writeX_header);
313 /* Copy the header we've written. */
315 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
316 writeX_header,
317 sizeof(writeX_header));
319 if (*buffer == NULL) {
320 DEBUG(0, ("Could not allocate inbuf of length %d\n",
321 (int)sizeof(writeX_header)));
322 return NT_STATUS_NO_MEMORY;
325 /* Work out the remaining bytes. */
326 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
327 *len_ret = newlen + 4;
328 return NT_STATUS_OK;
331 if (!valid_packet_size(len)) {
332 return NT_STATUS_INVALID_PARAMETER;
336 * Not a valid writeX call. Just do the standard
337 * talloc and return.
340 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
342 if (*buffer == NULL) {
343 DEBUG(0, ("Could not allocate inbuf of length %d\n",
344 (int)len+4));
345 return NT_STATUS_NO_MEMORY;
348 /* Copy in what we already read. */
349 memcpy(*buffer,
350 writeX_header,
351 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
352 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
354 if(toread > 0) {
355 status = read_packet_remainder(
356 sconn->sock,
357 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
358 timeout, toread);
360 if (!NT_STATUS_IS_OK(status)) {
361 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
362 nt_errstr(status)));
363 return status;
367 *len_ret = len + 4;
368 return NT_STATUS_OK;
371 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
372 struct smbd_server_connection *sconn,
373 char **buffer, unsigned int timeout,
374 size_t *p_unread, size_t *plen)
376 char lenbuf[4];
377 size_t len;
378 int min_recv_size = lp_min_receive_file_size();
379 NTSTATUS status;
381 *p_unread = 0;
383 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
384 &len);
385 if (!NT_STATUS_IS_OK(status)) {
386 return status;
389 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
390 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
391 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
392 !srv_is_signing_active(sconn) &&
393 sconn->smb1.echo_handler.trusted_fde == NULL) {
395 return receive_smb_raw_talloc_partial_read(
396 mem_ctx, lenbuf, sconn, buffer, timeout,
397 p_unread, plen);
400 if (!valid_packet_size(len)) {
401 return NT_STATUS_INVALID_PARAMETER;
405 * The +4 here can't wrap, we've checked the length above already.
408 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
410 if (*buffer == NULL) {
411 DEBUG(0, ("Could not allocate inbuf of length %d\n",
412 (int)len+4));
413 return NT_STATUS_NO_MEMORY;
416 memcpy(*buffer, lenbuf, sizeof(lenbuf));
418 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
419 if (!NT_STATUS_IS_OK(status)) {
420 return status;
423 *plen = len + 4;
424 return NT_STATUS_OK;
427 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
428 struct smbd_server_connection *sconn,
429 char **buffer, unsigned int timeout,
430 size_t *p_unread, bool *p_encrypted,
431 size_t *p_len,
432 uint32_t *seqnum,
433 bool trusted_channel)
435 size_t len = 0;
436 NTSTATUS status;
438 *p_encrypted = false;
440 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
441 p_unread, &len);
442 if (!NT_STATUS_IS_OK(status)) {
443 DEBUG(1, ("read_smb_length_return_keepalive failed for "
444 "client %s read error = %s.\n",
445 sconn->client_id.addr, nt_errstr(status)));
446 return status;
449 if (is_encrypted_packet((uint8_t *)*buffer)) {
450 status = srv_decrypt_buffer(*buffer);
451 if (!NT_STATUS_IS_OK(status)) {
452 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
453 "incoming packet! Error %s\n",
454 nt_errstr(status) ));
455 return status;
457 *p_encrypted = true;
460 /* Check the incoming SMB signature. */
461 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
462 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
463 "incoming packet!\n"));
464 return NT_STATUS_INVALID_NETWORK_RESPONSE;
467 *p_len = len;
468 return NT_STATUS_OK;
472 * Initialize a struct smb_request from an inbuf
475 static bool init_smb_request(struct smb_request *req,
476 struct smbd_server_connection *sconn,
477 const uint8 *inbuf,
478 size_t unread_bytes, bool encrypted,
479 uint32_t seqnum)
481 size_t req_size = smb_len(inbuf) + 4;
482 /* Ensure we have at least smb_size bytes. */
483 if (req_size < smb_size) {
484 DEBUG(0,("init_smb_request: invalid request size %u\n",
485 (unsigned int)req_size ));
486 return false;
488 req->cmd = CVAL(inbuf, smb_com);
489 req->flags2 = SVAL(inbuf, smb_flg2);
490 req->smbpid = SVAL(inbuf, smb_pid);
491 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
492 req->seqnum = seqnum;
493 req->vuid = SVAL(inbuf, smb_uid);
494 req->tid = SVAL(inbuf, smb_tid);
495 req->wct = CVAL(inbuf, smb_wct);
496 req->vwv = (uint16_t *)(inbuf+smb_vwv);
497 req->buflen = smb_buflen(inbuf);
498 req->buf = (const uint8_t *)smb_buf(inbuf);
499 req->unread_bytes = unread_bytes;
500 req->encrypted = encrypted;
501 req->sconn = sconn;
502 req->conn = conn_find(sconn,req->tid);
503 req->chain_fsp = NULL;
504 req->chain_outbuf = NULL;
505 req->done = false;
506 req->smb2req = NULL;
507 smb_init_perfcount_data(&req->pcd);
509 /* Ensure we have at least wct words and 2 bytes of bcc. */
510 if (smb_size + req->wct*2 > req_size) {
511 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
512 (unsigned int)req->wct,
513 (unsigned int)req_size));
514 return false;
516 /* Ensure bcc is correct. */
517 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
518 DEBUG(0,("init_smb_request: invalid bcc number %u "
519 "(wct = %u, size %u)\n",
520 (unsigned int)req->buflen,
521 (unsigned int)req->wct,
522 (unsigned int)req_size));
523 return false;
526 req->outbuf = NULL;
527 return true;
530 static void process_smb(struct smbd_server_connection *conn,
531 uint8_t *inbuf, size_t nread, size_t unread_bytes,
532 uint32_t seqnum, bool encrypted,
533 struct smb_perfcount_data *deferred_pcd);
535 static void smbd_deferred_open_timer(struct event_context *ev,
536 struct timed_event *te,
537 struct timeval _tval,
538 void *private_data)
540 struct pending_message_list *msg = talloc_get_type(private_data,
541 struct pending_message_list);
542 TALLOC_CTX *mem_ctx = talloc_tos();
543 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
544 uint8_t *inbuf;
546 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
547 msg->buf.length);
548 if (inbuf == NULL) {
549 exit_server("smbd_deferred_open_timer: talloc failed\n");
550 return;
553 /* We leave this message on the queue so the open code can
554 know this is a retry. */
555 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
556 (unsigned long long)mid ));
558 /* Mark the message as processed so this is not
559 * re-processed in error. */
560 msg->processed = true;
562 process_smb(smbd_server_conn, inbuf,
563 msg->buf.length, 0,
564 msg->seqnum, msg->encrypted, &msg->pcd);
566 /* If it's still there and was processed, remove it. */
567 msg = get_deferred_open_message_smb(mid);
568 if (msg && msg->processed) {
569 remove_deferred_open_message_smb(mid);
573 /****************************************************************************
574 Function to push a message onto the tail of a linked list of smb messages ready
575 for processing.
576 ****************************************************************************/
578 static bool push_queued_message(struct smb_request *req,
579 struct timeval request_time,
580 struct timeval end_time,
581 char *private_data, size_t private_len)
583 int msg_len = smb_len(req->inbuf) + 4;
584 struct pending_message_list *msg;
586 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
588 if(msg == NULL) {
589 DEBUG(0,("push_message: malloc fail (1)\n"));
590 return False;
593 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
594 if(msg->buf.data == NULL) {
595 DEBUG(0,("push_message: malloc fail (2)\n"));
596 TALLOC_FREE(msg);
597 return False;
600 msg->request_time = request_time;
601 msg->seqnum = req->seqnum;
602 msg->encrypted = req->encrypted;
603 msg->processed = false;
604 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
606 if (private_data) {
607 msg->private_data = data_blob_talloc(msg, private_data,
608 private_len);
609 if (msg->private_data.data == NULL) {
610 DEBUG(0,("push_message: malloc fail (3)\n"));
611 TALLOC_FREE(msg);
612 return False;
616 msg->te = event_add_timed(smbd_event_context(),
617 msg,
618 end_time,
619 smbd_deferred_open_timer,
620 msg);
621 if (!msg->te) {
622 DEBUG(0,("push_message: event_add_timed failed\n"));
623 TALLOC_FREE(msg);
624 return false;
627 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
629 DEBUG(10,("push_message: pushed message length %u on "
630 "deferred_open_queue\n", (unsigned int)msg_len));
632 return True;
635 /****************************************************************************
636 Function to delete a sharing violation open message by mid.
637 ****************************************************************************/
639 void remove_deferred_open_message_smb(uint64_t mid)
641 struct pending_message_list *pml;
643 if (smbd_server_conn->using_smb2) {
644 remove_deferred_open_message_smb2(smbd_server_conn, mid);
645 return;
648 for (pml = deferred_open_queue; pml; pml = pml->next) {
649 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
650 DEBUG(10,("remove_deferred_open_message_smb: "
651 "deleting mid %llu len %u\n",
652 (unsigned long long)mid,
653 (unsigned int)pml->buf.length ));
654 DLIST_REMOVE(deferred_open_queue, pml);
655 TALLOC_FREE(pml);
656 return;
661 /****************************************************************************
662 Move a sharing violation open retry message to the front of the list and
663 schedule it for immediate processing.
664 ****************************************************************************/
666 void schedule_deferred_open_message_smb(uint64_t mid)
668 struct pending_message_list *pml;
669 int i = 0;
671 if (smbd_server_conn->using_smb2) {
672 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
673 return;
676 for (pml = deferred_open_queue; pml; pml = pml->next) {
677 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
679 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
680 "msg_mid = %llu\n",
681 i++,
682 (unsigned long long)msg_mid ));
684 if (mid == msg_mid) {
685 struct timed_event *te;
687 if (pml->processed) {
688 /* A processed message should not be
689 * rescheduled. */
690 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
691 "message mid %llu was already processed\n",
692 (unsigned long long)msg_mid ));
693 continue;
696 DEBUG(10,("schedule_deferred_open_message_smb: "
697 "scheduling mid %llu\n",
698 (unsigned long long)mid ));
700 te = event_add_timed(smbd_event_context(),
701 pml,
702 timeval_zero(),
703 smbd_deferred_open_timer,
704 pml);
705 if (!te) {
706 DEBUG(10,("schedule_deferred_open_message_smb: "
707 "event_add_timed() failed, "
708 "skipping mid %llu\n",
709 (unsigned long long)msg_mid ));
712 TALLOC_FREE(pml->te);
713 pml->te = te;
714 DLIST_PROMOTE(deferred_open_queue, pml);
715 return;
719 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
720 "find message mid %llu\n",
721 (unsigned long long)mid ));
724 /****************************************************************************
725 Return true if this mid is on the deferred queue and was not yet processed.
726 ****************************************************************************/
728 bool open_was_deferred(uint64_t mid)
730 struct pending_message_list *pml;
732 if (smbd_server_conn->using_smb2) {
733 return open_was_deferred_smb2(smbd_server_conn, mid);
736 for (pml = deferred_open_queue; pml; pml = pml->next) {
737 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
738 return True;
741 return False;
744 /****************************************************************************
745 Return the message queued by this mid.
746 ****************************************************************************/
748 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
750 struct pending_message_list *pml;
752 for (pml = deferred_open_queue; pml; pml = pml->next) {
753 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
754 return pml;
757 return NULL;
760 /****************************************************************************
761 Get the state data queued by this mid.
762 ****************************************************************************/
764 bool get_deferred_open_message_state(struct smb_request *smbreq,
765 struct timeval *p_request_time,
766 void **pp_state)
768 struct pending_message_list *pml;
770 if (smbd_server_conn->using_smb2) {
771 return get_deferred_open_message_state_smb2(smbreq->smb2req,
772 p_request_time,
773 pp_state);
776 pml = get_deferred_open_message_smb(smbreq->mid);
777 if (!pml) {
778 return false;
780 if (p_request_time) {
781 *p_request_time = pml->request_time;
783 if (pp_state) {
784 *pp_state = (void *)pml->private_data.data;
786 return true;
789 /****************************************************************************
790 Function to push a deferred open smb message onto a linked list of local smb
791 messages ready for processing.
792 ****************************************************************************/
794 bool push_deferred_open_message_smb(struct smb_request *req,
795 struct timeval request_time,
796 struct timeval timeout,
797 struct file_id id,
798 char *private_data, size_t priv_len)
800 struct timeval end_time;
802 if (req->smb2req) {
803 return push_deferred_open_message_smb2(req->smb2req,
804 request_time,
805 timeout,
807 private_data,
808 priv_len);
811 if (req->unread_bytes) {
812 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
813 "unread_bytes = %u\n",
814 (unsigned int)req->unread_bytes ));
815 smb_panic("push_deferred_open_message_smb: "
816 "logic error unread_bytes != 0" );
819 end_time = timeval_sum(&request_time, &timeout);
821 DEBUG(10,("push_deferred_open_message_smb: pushing message "
822 "len %u mid %llu timeout time [%u.%06u]\n",
823 (unsigned int) smb_len(req->inbuf)+4,
824 (unsigned long long)req->mid,
825 (unsigned int)end_time.tv_sec,
826 (unsigned int)end_time.tv_usec));
828 return push_queued_message(req, request_time, end_time,
829 private_data, priv_len);
832 struct idle_event {
833 struct timed_event *te;
834 struct timeval interval;
835 char *name;
836 bool (*handler)(const struct timeval *now, void *private_data);
837 void *private_data;
840 static void smbd_idle_event_handler(struct event_context *ctx,
841 struct timed_event *te,
842 struct timeval now,
843 void *private_data)
845 struct idle_event *event =
846 talloc_get_type_abort(private_data, struct idle_event);
848 TALLOC_FREE(event->te);
850 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
851 event->name, event->te));
853 if (!event->handler(&now, event->private_data)) {
854 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
855 event->name, event->te));
856 /* Don't repeat, delete ourselves */
857 TALLOC_FREE(event);
858 return;
861 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
862 event->name, event->te));
864 event->te = event_add_timed(ctx, event,
865 timeval_sum(&now, &event->interval),
866 smbd_idle_event_handler, event);
868 /* We can't do much but fail here. */
869 SMB_ASSERT(event->te != NULL);
872 struct idle_event *event_add_idle(struct event_context *event_ctx,
873 TALLOC_CTX *mem_ctx,
874 struct timeval interval,
875 const char *name,
876 bool (*handler)(const struct timeval *now,
877 void *private_data),
878 void *private_data)
880 struct idle_event *result;
881 struct timeval now = timeval_current();
883 result = TALLOC_P(mem_ctx, struct idle_event);
884 if (result == NULL) {
885 DEBUG(0, ("talloc failed\n"));
886 return NULL;
889 result->interval = interval;
890 result->handler = handler;
891 result->private_data = private_data;
893 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
894 DEBUG(0, ("talloc failed\n"));
895 TALLOC_FREE(result);
896 return NULL;
899 result->te = event_add_timed(event_ctx, result,
900 timeval_sum(&now, &interval),
901 smbd_idle_event_handler, result);
902 if (result->te == NULL) {
903 DEBUG(0, ("event_add_timed failed\n"));
904 TALLOC_FREE(result);
905 return NULL;
908 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
909 return result;
912 static void smbd_sig_term_handler(struct tevent_context *ev,
913 struct tevent_signal *se,
914 int signum,
915 int count,
916 void *siginfo,
917 void *private_data)
919 exit_server_cleanly("termination signal");
922 void smbd_setup_sig_term_handler(void)
924 struct tevent_signal *se;
926 se = tevent_add_signal(smbd_event_context(),
927 smbd_event_context(),
928 SIGTERM, 0,
929 smbd_sig_term_handler,
930 NULL);
931 if (!se) {
932 exit_server("failed to setup SIGTERM handler");
936 static void smbd_sig_hup_handler(struct tevent_context *ev,
937 struct tevent_signal *se,
938 int signum,
939 int count,
940 void *siginfo,
941 void *private_data)
943 struct messaging_context *msg_ctx = talloc_get_type_abort(
944 private_data, struct messaging_context);
945 change_to_root_user();
946 DEBUG(1,("Reloading services after SIGHUP\n"));
947 reload_services(msg_ctx, smbd_server_conn->sock, False);
948 if (am_parent) {
949 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
953 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
954 struct messaging_context *msg_ctx)
956 struct tevent_signal *se;
958 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
959 msg_ctx);
960 if (!se) {
961 exit_server("failed to setup SIGHUP handler");
965 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
967 int timeout;
968 int num_pfds = 0;
969 int ret;
970 bool retry;
972 timeout = SMBD_SELECT_TIMEOUT * 1000;
975 * Are there any timed events waiting ? If so, ensure we don't
976 * select for longer than it would take to wait for them.
979 event_add_to_poll_args(smbd_event_context(), conn,
980 &conn->pfds, &num_pfds, &timeout);
982 /* Process a signal and timed events now... */
983 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
984 return NT_STATUS_RETRY;
988 int sav;
989 START_PROFILE(smbd_idle);
991 ret = sys_poll(conn->pfds, num_pfds, timeout);
992 sav = errno;
994 END_PROFILE(smbd_idle);
995 errno = sav;
998 if (ret == -1 && errno != EINTR) {
999 return map_nt_error_from_unix(errno);
1002 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1003 num_pfds);
1004 if (retry) {
1005 return NT_STATUS_RETRY;
1008 /* Did we timeout ? */
1009 if (ret == 0) {
1010 return NT_STATUS_RETRY;
1013 /* should not be reached */
1014 return NT_STATUS_INTERNAL_ERROR;
1018 * Only allow 5 outstanding trans requests. We're allocating memory, so
1019 * prevent a DoS.
1022 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1024 int count = 0;
1025 for (; list != NULL; list = list->next) {
1027 if (list->mid == mid) {
1028 return NT_STATUS_INVALID_PARAMETER;
1031 count += 1;
1033 if (count > 5) {
1034 return NT_STATUS_INSUFFICIENT_RESOURCES;
1037 return NT_STATUS_OK;
1041 These flags determine some of the permissions required to do an operation
1043 Note that I don't set NEED_WRITE on some write operations because they
1044 are used by some brain-dead clients when printing, and I don't want to
1045 force write permissions on print services.
1047 #define AS_USER (1<<0)
1048 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1049 #define TIME_INIT (1<<2)
1050 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1051 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1052 #define DO_CHDIR (1<<6)
1055 define a list of possible SMB messages and their corresponding
1056 functions. Any message that has a NULL function is unimplemented -
1057 please feel free to contribute implementations!
1059 static const struct smb_message_struct {
1060 const char *name;
1061 void (*fn)(struct smb_request *req);
1062 int flags;
1063 } smb_messages[256] = {
1065 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1066 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1067 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1068 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1069 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1070 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1071 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1072 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1073 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1074 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1075 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1076 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1077 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1078 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1079 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1080 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1081 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1082 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1083 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1084 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1085 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1086 /* 0x15 */ { NULL, NULL, 0 },
1087 /* 0x16 */ { NULL, NULL, 0 },
1088 /* 0x17 */ { NULL, NULL, 0 },
1089 /* 0x18 */ { NULL, NULL, 0 },
1090 /* 0x19 */ { NULL, NULL, 0 },
1091 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1092 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1093 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1094 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1095 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1096 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1097 /* 0x20 */ { "SMBwritec", NULL,0},
1098 /* 0x21 */ { NULL, NULL, 0 },
1099 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1100 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1101 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1102 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1103 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1104 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1105 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1106 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1107 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1108 /* 0x2b */ { "SMBecho",reply_echo,0},
1109 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1110 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1111 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1112 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1113 /* 0x30 */ { NULL, NULL, 0 },
1114 /* 0x31 */ { NULL, NULL, 0 },
1115 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1116 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1117 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1118 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1119 /* 0x36 */ { NULL, NULL, 0 },
1120 /* 0x37 */ { NULL, NULL, 0 },
1121 /* 0x38 */ { NULL, NULL, 0 },
1122 /* 0x39 */ { NULL, NULL, 0 },
1123 /* 0x3a */ { NULL, NULL, 0 },
1124 /* 0x3b */ { NULL, NULL, 0 },
1125 /* 0x3c */ { NULL, NULL, 0 },
1126 /* 0x3d */ { NULL, NULL, 0 },
1127 /* 0x3e */ { NULL, NULL, 0 },
1128 /* 0x3f */ { NULL, NULL, 0 },
1129 /* 0x40 */ { NULL, NULL, 0 },
1130 /* 0x41 */ { NULL, NULL, 0 },
1131 /* 0x42 */ { NULL, NULL, 0 },
1132 /* 0x43 */ { NULL, NULL, 0 },
1133 /* 0x44 */ { NULL, NULL, 0 },
1134 /* 0x45 */ { NULL, NULL, 0 },
1135 /* 0x46 */ { NULL, NULL, 0 },
1136 /* 0x47 */ { NULL, NULL, 0 },
1137 /* 0x48 */ { NULL, NULL, 0 },
1138 /* 0x49 */ { NULL, NULL, 0 },
1139 /* 0x4a */ { NULL, NULL, 0 },
1140 /* 0x4b */ { NULL, NULL, 0 },
1141 /* 0x4c */ { NULL, NULL, 0 },
1142 /* 0x4d */ { NULL, NULL, 0 },
1143 /* 0x4e */ { NULL, NULL, 0 },
1144 /* 0x4f */ { NULL, NULL, 0 },
1145 /* 0x50 */ { NULL, NULL, 0 },
1146 /* 0x51 */ { NULL, NULL, 0 },
1147 /* 0x52 */ { NULL, NULL, 0 },
1148 /* 0x53 */ { NULL, NULL, 0 },
1149 /* 0x54 */ { NULL, NULL, 0 },
1150 /* 0x55 */ { NULL, NULL, 0 },
1151 /* 0x56 */ { NULL, NULL, 0 },
1152 /* 0x57 */ { NULL, NULL, 0 },
1153 /* 0x58 */ { NULL, NULL, 0 },
1154 /* 0x59 */ { NULL, NULL, 0 },
1155 /* 0x5a */ { NULL, NULL, 0 },
1156 /* 0x5b */ { NULL, NULL, 0 },
1157 /* 0x5c */ { NULL, NULL, 0 },
1158 /* 0x5d */ { NULL, NULL, 0 },
1159 /* 0x5e */ { NULL, NULL, 0 },
1160 /* 0x5f */ { NULL, NULL, 0 },
1161 /* 0x60 */ { NULL, NULL, 0 },
1162 /* 0x61 */ { NULL, NULL, 0 },
1163 /* 0x62 */ { NULL, NULL, 0 },
1164 /* 0x63 */ { NULL, NULL, 0 },
1165 /* 0x64 */ { NULL, NULL, 0 },
1166 /* 0x65 */ { NULL, NULL, 0 },
1167 /* 0x66 */ { NULL, NULL, 0 },
1168 /* 0x67 */ { NULL, NULL, 0 },
1169 /* 0x68 */ { NULL, NULL, 0 },
1170 /* 0x69 */ { NULL, NULL, 0 },
1171 /* 0x6a */ { NULL, NULL, 0 },
1172 /* 0x6b */ { NULL, NULL, 0 },
1173 /* 0x6c */ { NULL, NULL, 0 },
1174 /* 0x6d */ { NULL, NULL, 0 },
1175 /* 0x6e */ { NULL, NULL, 0 },
1176 /* 0x6f */ { NULL, NULL, 0 },
1177 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1178 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1179 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1180 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1181 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1182 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1183 /* 0x76 */ { NULL, NULL, 0 },
1184 /* 0x77 */ { NULL, NULL, 0 },
1185 /* 0x78 */ { NULL, NULL, 0 },
1186 /* 0x79 */ { NULL, NULL, 0 },
1187 /* 0x7a */ { NULL, NULL, 0 },
1188 /* 0x7b */ { NULL, NULL, 0 },
1189 /* 0x7c */ { NULL, NULL, 0 },
1190 /* 0x7d */ { NULL, NULL, 0 },
1191 /* 0x7e */ { NULL, NULL, 0 },
1192 /* 0x7f */ { NULL, NULL, 0 },
1193 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1194 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1195 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1196 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1197 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1198 /* 0x85 */ { NULL, NULL, 0 },
1199 /* 0x86 */ { NULL, NULL, 0 },
1200 /* 0x87 */ { NULL, NULL, 0 },
1201 /* 0x88 */ { NULL, NULL, 0 },
1202 /* 0x89 */ { NULL, NULL, 0 },
1203 /* 0x8a */ { NULL, NULL, 0 },
1204 /* 0x8b */ { NULL, NULL, 0 },
1205 /* 0x8c */ { NULL, NULL, 0 },
1206 /* 0x8d */ { NULL, NULL, 0 },
1207 /* 0x8e */ { NULL, NULL, 0 },
1208 /* 0x8f */ { NULL, NULL, 0 },
1209 /* 0x90 */ { NULL, NULL, 0 },
1210 /* 0x91 */ { NULL, NULL, 0 },
1211 /* 0x92 */ { NULL, NULL, 0 },
1212 /* 0x93 */ { NULL, NULL, 0 },
1213 /* 0x94 */ { NULL, NULL, 0 },
1214 /* 0x95 */ { NULL, NULL, 0 },
1215 /* 0x96 */ { NULL, NULL, 0 },
1216 /* 0x97 */ { NULL, NULL, 0 },
1217 /* 0x98 */ { NULL, NULL, 0 },
1218 /* 0x99 */ { NULL, NULL, 0 },
1219 /* 0x9a */ { NULL, NULL, 0 },
1220 /* 0x9b */ { NULL, NULL, 0 },
1221 /* 0x9c */ { NULL, NULL, 0 },
1222 /* 0x9d */ { NULL, NULL, 0 },
1223 /* 0x9e */ { NULL, NULL, 0 },
1224 /* 0x9f */ { NULL, NULL, 0 },
1225 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1226 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1227 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1228 /* 0xa3 */ { NULL, NULL, 0 },
1229 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1230 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1231 /* 0xa6 */ { NULL, NULL, 0 },
1232 /* 0xa7 */ { NULL, NULL, 0 },
1233 /* 0xa8 */ { NULL, NULL, 0 },
1234 /* 0xa9 */ { NULL, NULL, 0 },
1235 /* 0xaa */ { NULL, NULL, 0 },
1236 /* 0xab */ { NULL, NULL, 0 },
1237 /* 0xac */ { NULL, NULL, 0 },
1238 /* 0xad */ { NULL, NULL, 0 },
1239 /* 0xae */ { NULL, NULL, 0 },
1240 /* 0xaf */ { NULL, NULL, 0 },
1241 /* 0xb0 */ { NULL, NULL, 0 },
1242 /* 0xb1 */ { NULL, NULL, 0 },
1243 /* 0xb2 */ { NULL, NULL, 0 },
1244 /* 0xb3 */ { NULL, NULL, 0 },
1245 /* 0xb4 */ { NULL, NULL, 0 },
1246 /* 0xb5 */ { NULL, NULL, 0 },
1247 /* 0xb6 */ { NULL, NULL, 0 },
1248 /* 0xb7 */ { NULL, NULL, 0 },
1249 /* 0xb8 */ { NULL, NULL, 0 },
1250 /* 0xb9 */ { NULL, NULL, 0 },
1251 /* 0xba */ { NULL, NULL, 0 },
1252 /* 0xbb */ { NULL, NULL, 0 },
1253 /* 0xbc */ { NULL, NULL, 0 },
1254 /* 0xbd */ { NULL, NULL, 0 },
1255 /* 0xbe */ { NULL, NULL, 0 },
1256 /* 0xbf */ { NULL, NULL, 0 },
1257 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1258 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1259 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1260 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1261 /* 0xc4 */ { NULL, NULL, 0 },
1262 /* 0xc5 */ { NULL, NULL, 0 },
1263 /* 0xc6 */ { NULL, NULL, 0 },
1264 /* 0xc7 */ { NULL, NULL, 0 },
1265 /* 0xc8 */ { NULL, NULL, 0 },
1266 /* 0xc9 */ { NULL, NULL, 0 },
1267 /* 0xca */ { NULL, NULL, 0 },
1268 /* 0xcb */ { NULL, NULL, 0 },
1269 /* 0xcc */ { NULL, NULL, 0 },
1270 /* 0xcd */ { NULL, NULL, 0 },
1271 /* 0xce */ { NULL, NULL, 0 },
1272 /* 0xcf */ { NULL, NULL, 0 },
1273 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1274 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1275 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1276 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1277 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1278 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1279 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1280 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1281 /* 0xd8 */ { NULL, NULL, 0 },
1282 /* 0xd9 */ { NULL, NULL, 0 },
1283 /* 0xda */ { NULL, NULL, 0 },
1284 /* 0xdb */ { NULL, NULL, 0 },
1285 /* 0xdc */ { NULL, NULL, 0 },
1286 /* 0xdd */ { NULL, NULL, 0 },
1287 /* 0xde */ { NULL, NULL, 0 },
1288 /* 0xdf */ { NULL, NULL, 0 },
1289 /* 0xe0 */ { NULL, NULL, 0 },
1290 /* 0xe1 */ { NULL, NULL, 0 },
1291 /* 0xe2 */ { NULL, NULL, 0 },
1292 /* 0xe3 */ { NULL, NULL, 0 },
1293 /* 0xe4 */ { NULL, NULL, 0 },
1294 /* 0xe5 */ { NULL, NULL, 0 },
1295 /* 0xe6 */ { NULL, NULL, 0 },
1296 /* 0xe7 */ { NULL, NULL, 0 },
1297 /* 0xe8 */ { NULL, NULL, 0 },
1298 /* 0xe9 */ { NULL, NULL, 0 },
1299 /* 0xea */ { NULL, NULL, 0 },
1300 /* 0xeb */ { NULL, NULL, 0 },
1301 /* 0xec */ { NULL, NULL, 0 },
1302 /* 0xed */ { NULL, NULL, 0 },
1303 /* 0xee */ { NULL, NULL, 0 },
1304 /* 0xef */ { NULL, NULL, 0 },
1305 /* 0xf0 */ { NULL, NULL, 0 },
1306 /* 0xf1 */ { NULL, NULL, 0 },
1307 /* 0xf2 */ { NULL, NULL, 0 },
1308 /* 0xf3 */ { NULL, NULL, 0 },
1309 /* 0xf4 */ { NULL, NULL, 0 },
1310 /* 0xf5 */ { NULL, NULL, 0 },
1311 /* 0xf6 */ { NULL, NULL, 0 },
1312 /* 0xf7 */ { NULL, NULL, 0 },
1313 /* 0xf8 */ { NULL, NULL, 0 },
1314 /* 0xf9 */ { NULL, NULL, 0 },
1315 /* 0xfa */ { NULL, NULL, 0 },
1316 /* 0xfb */ { NULL, NULL, 0 },
1317 /* 0xfc */ { NULL, NULL, 0 },
1318 /* 0xfd */ { NULL, NULL, 0 },
1319 /* 0xfe */ { NULL, NULL, 0 },
1320 /* 0xff */ { NULL, NULL, 0 }
1324 /*******************************************************************
1325 allocate and initialize a reply packet
1326 ********************************************************************/
1328 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1329 const char *inbuf, char **outbuf, uint8_t num_words,
1330 uint32_t num_bytes)
1333 * Protect against integer wrap
1335 if ((num_bytes > 0xffffff)
1336 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1337 char *msg;
1338 if (asprintf(&msg, "num_bytes too large: %u",
1339 (unsigned)num_bytes) == -1) {
1340 msg = CONST_DISCARD(char *, "num_bytes too large");
1342 smb_panic(msg);
1345 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1346 smb_size + num_words*2 + num_bytes);
1347 if (*outbuf == NULL) {
1348 return false;
1351 construct_reply_common(req, inbuf, *outbuf);
1352 srv_set_message(*outbuf, num_words, num_bytes, false);
1354 * Zero out the word area, the caller has to take care of the bcc area
1355 * himself
1357 if (num_words != 0) {
1358 memset(*outbuf + smb_vwv0, 0, num_words*2);
1361 return true;
1364 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1366 char *outbuf;
1367 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1368 num_bytes)) {
1369 smb_panic("could not allocate output buffer\n");
1371 req->outbuf = (uint8_t *)outbuf;
1375 /*******************************************************************
1376 Dump a packet to a file.
1377 ********************************************************************/
1379 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1381 int fd, i;
1382 char *fname = NULL;
1383 if (DEBUGLEVEL < 50) {
1384 return;
1387 if (len < 4) len = smb_len(data)+4;
1388 for (i=1;i<100;i++) {
1389 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1390 type ? "req" : "resp") == -1) {
1391 return;
1393 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1394 if (fd != -1 || errno != EEXIST) break;
1396 if (fd != -1) {
1397 ssize_t ret = write(fd, data, len);
1398 if (ret != len)
1399 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1400 close(fd);
1401 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1403 SAFE_FREE(fname);
1406 /****************************************************************************
1407 Prepare everything for calling the actual request function, and potentially
1408 call the request function via the "new" interface.
1410 Return False if the "legacy" function needs to be called, everything is
1411 prepared.
1413 Return True if we're done.
1415 I know this API sucks, but it is the one with the least code change I could
1416 find.
1417 ****************************************************************************/
1419 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1421 int flags;
1422 uint16 session_tag;
1423 connection_struct *conn = NULL;
1424 struct smbd_server_connection *sconn = req->sconn;
1426 errno = 0;
1428 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1429 * so subtract 4 from it. */
1430 if (!valid_smb_header(req->inbuf)
1431 || (size < (smb_size - 4))) {
1432 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1433 smb_len(req->inbuf)));
1434 exit_server_cleanly("Non-SMB packet");
1437 if (smb_messages[type].fn == NULL) {
1438 DEBUG(0,("Unknown message type %d!\n",type));
1439 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1440 reply_unknown_new(req, type);
1441 return NULL;
1444 flags = smb_messages[type].flags;
1446 /* In share mode security we must ignore the vuid. */
1447 session_tag = (lp_security() == SEC_SHARE)
1448 ? UID_FIELD_INVALID : req->vuid;
1449 conn = req->conn;
1451 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1452 (int)sys_getpid(), (unsigned long)conn));
1454 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1456 /* Ensure this value is replaced in the incoming packet. */
1457 SSVAL(req->inbuf,smb_uid,session_tag);
1460 * Ensure the correct username is in current_user_info. This is a
1461 * really ugly bugfix for problems with multiple session_setup_and_X's
1462 * being done and allowing %U and %G substitutions to work correctly.
1463 * There is a reason this code is done here, don't move it unless you
1464 * know what you're doing... :-).
1465 * JRA.
1468 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1469 user_struct *vuser = NULL;
1471 sconn->smb1.sessions.last_session_tag = session_tag;
1472 if(session_tag != UID_FIELD_INVALID) {
1473 vuser = get_valid_user_struct(sconn, session_tag);
1474 if (vuser) {
1475 set_current_user_info(
1476 vuser->session_info->sanitized_username,
1477 vuser->session_info->unix_name,
1478 vuser->session_info->info3->base.domain.string);
1483 /* Does this call need to be run as the connected user? */
1484 if (flags & AS_USER) {
1486 /* Does this call need a valid tree connection? */
1487 if (!conn) {
1489 * Amazingly, the error code depends on the command
1490 * (from Samba4).
1492 if (type == SMBntcreateX) {
1493 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1494 } else {
1495 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1497 return NULL;
1500 if (!change_to_user(conn,session_tag)) {
1501 DEBUG(0, ("Error: Could not change to user. Removing "
1502 "deferred open, mid=%llu.\n",
1503 (unsigned long long)req->mid));
1504 reply_force_doserror(req, ERRSRV, ERRbaduid);
1505 return conn;
1508 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1510 /* Does it need write permission? */
1511 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1512 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1513 return conn;
1516 /* IPC services are limited */
1517 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1518 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1519 return conn;
1521 } else {
1522 /* This call needs to be run as root */
1523 change_to_root_user();
1526 /* load service specific parameters */
1527 if (conn) {
1528 if (req->encrypted) {
1529 conn->encrypted_tid = true;
1530 /* encrypted required from now on. */
1531 conn->encrypt_level = Required;
1532 } else if (ENCRYPTION_REQUIRED(conn)) {
1533 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1534 exit_server_cleanly("encryption required "
1535 "on connection");
1536 return conn;
1540 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1541 (flags & (AS_USER|DO_CHDIR)
1542 ?True:False))) {
1543 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1544 return conn;
1546 conn->num_smb_operations++;
1549 /* does this protocol need to be run as guest? */
1550 if ((flags & AS_GUEST)
1551 && (!change_to_guest() ||
1552 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1553 sconn->client_id.name,
1554 sconn->client_id.addr))) {
1555 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1556 return conn;
1559 smb_messages[type].fn(req);
1560 return req->conn;
1563 /****************************************************************************
1564 Construct a reply to the incoming packet.
1565 ****************************************************************************/
1567 static void construct_reply(struct smbd_server_connection *sconn,
1568 char *inbuf, int size, size_t unread_bytes,
1569 uint32_t seqnum, bool encrypted,
1570 struct smb_perfcount_data *deferred_pcd)
1572 connection_struct *conn;
1573 struct smb_request *req;
1575 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1576 smb_panic("could not allocate smb_request");
1579 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1580 encrypted, seqnum)) {
1581 exit_server_cleanly("Invalid SMB request");
1584 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1586 /* we popped this message off the queue - keep original perf data */
1587 if (deferred_pcd)
1588 req->pcd = *deferred_pcd;
1589 else {
1590 SMB_PERFCOUNT_START(&req->pcd);
1591 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1592 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1595 conn = switch_message(req->cmd, req, size);
1597 if (req->unread_bytes) {
1598 /* writeX failed. drain socket. */
1599 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1600 req->unread_bytes) {
1601 smb_panic("failed to drain pending bytes");
1603 req->unread_bytes = 0;
1606 if (req->done) {
1607 TALLOC_FREE(req);
1608 return;
1611 if (req->outbuf == NULL) {
1612 return;
1615 if (CVAL(req->outbuf,0) == 0) {
1616 show_msg((char *)req->outbuf);
1619 if (!srv_send_smb(req->sconn,
1620 (char *)req->outbuf,
1621 true, req->seqnum+1,
1622 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1623 &req->pcd)) {
1624 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1627 TALLOC_FREE(req);
1629 return;
1632 /****************************************************************************
1633 Process an smb from the client
1634 ****************************************************************************/
1635 static void process_smb(struct smbd_server_connection *sconn,
1636 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1637 uint32_t seqnum, bool encrypted,
1638 struct smb_perfcount_data *deferred_pcd)
1640 int msg_type = CVAL(inbuf,0);
1642 DO_PROFILE_INC(smb_count);
1644 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1645 smb_len(inbuf) ) );
1646 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1647 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1649 if (msg_type != 0) {
1651 * NetBIOS session request, keepalive, etc.
1653 reply_special(sconn, (char *)inbuf, nread);
1654 goto done;
1657 if (sconn->using_smb2) {
1658 /* At this point we're not really using smb2,
1659 * we make the decision here.. */
1660 if (smbd_is_smb2_header(inbuf, nread)) {
1661 smbd_smb2_first_negprot(sconn, inbuf, nread);
1662 return;
1663 } else if (nread >= smb_size && valid_smb_header(inbuf)
1664 && CVAL(inbuf, smb_com) != 0x72) {
1665 /* This is a non-negprot SMB1 packet.
1666 Disable SMB2 from now on. */
1667 sconn->using_smb2 = false;
1671 show_msg((char *)inbuf);
1673 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1674 encrypted, deferred_pcd);
1675 sconn->trans_num++;
1677 done:
1678 sconn->smb1.num_requests++;
1680 /* The timeout_processing function isn't run nearly
1681 often enough to implement 'max log size' without
1682 overrunning the size of the file by many megabytes.
1683 This is especially true if we are running at debug
1684 level 10. Checking every 50 SMBs is a nice
1685 tradeoff of performance vs log file size overrun. */
1687 if ((sconn->smb1.num_requests % 50) == 0 &&
1688 need_to_check_log_size()) {
1689 change_to_root_user();
1690 check_log_size();
1694 /****************************************************************************
1695 Return a string containing the function name of a SMB command.
1696 ****************************************************************************/
1698 const char *smb_fn_name(int type)
1700 const char *unknown_name = "SMBunknown";
1702 if (smb_messages[type].name == NULL)
1703 return(unknown_name);
1705 return(smb_messages[type].name);
1708 /****************************************************************************
1709 Helper functions for contruct_reply.
1710 ****************************************************************************/
1712 void add_to_common_flags2(uint32 v)
1714 common_flags2 |= v;
1717 void remove_from_common_flags2(uint32 v)
1719 common_flags2 &= ~v;
1722 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1723 char *outbuf)
1725 srv_set_message(outbuf,0,0,false);
1727 SCVAL(outbuf, smb_com, req->cmd);
1728 SIVAL(outbuf,smb_rcls,0);
1729 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1730 SSVAL(outbuf,smb_flg2,
1731 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1732 common_flags2);
1733 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1735 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1736 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1737 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1738 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1741 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1743 construct_reply_common(req, (char *)req->inbuf, outbuf);
1747 * How many bytes have we already accumulated up to the current wct field
1748 * offset?
1751 size_t req_wct_ofs(struct smb_request *req)
1753 size_t buf_size;
1755 if (req->chain_outbuf == NULL) {
1756 return smb_wct - 4;
1758 buf_size = talloc_get_size(req->chain_outbuf);
1759 if ((buf_size % 4) != 0) {
1760 buf_size += (4 - (buf_size % 4));
1762 return buf_size - 4;
1766 * Hack around reply_nterror & friends not being aware of chained requests,
1767 * generating illegal (i.e. wct==0) chain replies.
1770 static void fixup_chain_error_packet(struct smb_request *req)
1772 uint8_t *outbuf = req->outbuf;
1773 req->outbuf = NULL;
1774 reply_outbuf(req, 2, 0);
1775 memcpy(req->outbuf, outbuf, smb_wct);
1776 TALLOC_FREE(outbuf);
1777 SCVAL(req->outbuf, smb_vwv0, 0xff);
1781 * @brief Find the smb_cmd offset of the last command pushed
1782 * @param[in] buf The buffer we're building up
1783 * @retval Where can we put our next andx cmd?
1785 * While chaining requests, the "next" request we're looking at needs to put
1786 * its SMB_Command before the data the previous request already built up added
1787 * to the chain. Find the offset to the place where we have to put our cmd.
1790 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1792 uint8_t cmd;
1793 size_t ofs;
1795 cmd = CVAL(buf, smb_com);
1797 SMB_ASSERT(is_andx_req(cmd));
1799 ofs = smb_vwv0;
1801 while (CVAL(buf, ofs) != 0xff) {
1803 if (!is_andx_req(CVAL(buf, ofs))) {
1804 return false;
1808 * ofs is from start of smb header, so add the 4 length
1809 * bytes. The next cmd is right after the wct field.
1811 ofs = SVAL(buf, ofs+2) + 4 + 1;
1813 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1816 *pofs = ofs;
1817 return true;
1821 * @brief Do the smb chaining at a buffer level
1822 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1823 * @param[in] smb_command The command that we want to issue
1824 * @param[in] wct How many words?
1825 * @param[in] vwv The words, already in network order
1826 * @param[in] bytes_alignment How shall we align "bytes"?
1827 * @param[in] num_bytes How many bytes?
1828 * @param[in] bytes The data the request ships
1830 * smb_splice_chain() adds the vwv and bytes to the request already present in
1831 * *poutbuf.
1834 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1835 uint8_t wct, const uint16_t *vwv,
1836 size_t bytes_alignment,
1837 uint32_t num_bytes, const uint8_t *bytes)
1839 uint8_t *outbuf;
1840 size_t old_size, new_size;
1841 size_t ofs;
1842 size_t chain_padding = 0;
1843 size_t bytes_padding = 0;
1844 bool first_request;
1846 old_size = talloc_get_size(*poutbuf);
1849 * old_size == smb_wct means we're pushing the first request in for
1850 * libsmb/
1853 first_request = (old_size == smb_wct);
1855 if (!first_request && ((old_size % 4) != 0)) {
1857 * Align the wct field of subsequent requests to a 4-byte
1858 * boundary
1860 chain_padding = 4 - (old_size % 4);
1864 * After the old request comes the new wct field (1 byte), the vwv's
1865 * and the num_bytes field. After at we might need to align the bytes
1866 * given to us to "bytes_alignment", increasing the num_bytes value.
1869 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1871 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1872 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1875 new_size += bytes_padding + num_bytes;
1877 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1878 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1879 (unsigned)new_size));
1880 return false;
1883 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1884 if (outbuf == NULL) {
1885 DEBUG(0, ("talloc failed\n"));
1886 return false;
1888 *poutbuf = outbuf;
1890 if (first_request) {
1891 SCVAL(outbuf, smb_com, smb_command);
1892 } else {
1893 size_t andx_cmd_ofs;
1895 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1896 DEBUG(1, ("invalid command chain\n"));
1897 *poutbuf = TALLOC_REALLOC_ARRAY(
1898 NULL, *poutbuf, uint8_t, old_size);
1899 return false;
1902 if (chain_padding != 0) {
1903 memset(outbuf + old_size, 0, chain_padding);
1904 old_size += chain_padding;
1907 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1908 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1911 ofs = old_size;
1914 * Push the chained request:
1916 * wct field
1919 SCVAL(outbuf, ofs, wct);
1920 ofs += 1;
1923 * vwv array
1926 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1927 ofs += sizeof(uint16_t) * wct;
1930 * bcc (byte count)
1933 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1934 ofs += sizeof(uint16_t);
1937 * padding
1940 if (bytes_padding != 0) {
1941 memset(outbuf + ofs, 0, bytes_padding);
1942 ofs += bytes_padding;
1946 * The bytes field
1949 memcpy(outbuf + ofs, bytes, num_bytes);
1951 return true;
1954 /****************************************************************************
1955 Construct a chained reply and add it to the already made reply
1956 ****************************************************************************/
1958 void chain_reply(struct smb_request *req)
1960 size_t smblen = smb_len(req->inbuf);
1961 size_t already_used, length_needed;
1962 uint8_t chain_cmd;
1963 uint32_t chain_offset; /* uint32_t to avoid overflow */
1965 uint8_t wct;
1966 uint16_t *vwv;
1967 uint16_t buflen;
1968 uint8_t *buf;
1970 if (IVAL(req->outbuf, smb_rcls) != 0) {
1971 fixup_chain_error_packet(req);
1975 * Any of the AndX requests and replies have at least a wct of
1976 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1977 * beginning of the SMB header to the next wct field.
1979 * None of the AndX requests put anything valuable in vwv[0] and [1],
1980 * so we can overwrite it here to form the chain.
1983 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1984 if (req->chain_outbuf == NULL) {
1985 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1986 req, req->outbuf, uint8_t,
1987 smb_len(req->outbuf) + 4);
1988 if (req->chain_outbuf == NULL) {
1989 smb_panic("talloc failed");
1992 req->outbuf = NULL;
1993 goto error;
1997 * Here we assume that this is the end of the chain. For that we need
1998 * to set "next command" to 0xff and the offset to 0. If we later find
1999 * more commands in the chain, this will be overwritten again.
2002 SCVAL(req->outbuf, smb_vwv0, 0xff);
2003 SCVAL(req->outbuf, smb_vwv0+1, 0);
2004 SSVAL(req->outbuf, smb_vwv1, 0);
2006 if (req->chain_outbuf == NULL) {
2008 * In req->chain_outbuf we collect all the replies. Start the
2009 * chain by copying in the first reply.
2011 * We do the realloc because later on we depend on
2012 * talloc_get_size to determine the length of
2013 * chain_outbuf. The reply_xxx routines might have
2014 * over-allocated (reply_pipe_read_and_X used to be such an
2015 * example).
2017 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2018 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2019 if (req->chain_outbuf == NULL) {
2020 smb_panic("talloc failed");
2022 req->outbuf = NULL;
2023 } else {
2025 * Update smb headers where subsequent chained commands
2026 * may have updated them.
2028 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2029 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2031 if (!smb_splice_chain(&req->chain_outbuf,
2032 CVAL(req->outbuf, smb_com),
2033 CVAL(req->outbuf, smb_wct),
2034 (uint16_t *)(req->outbuf + smb_vwv),
2035 0, smb_buflen(req->outbuf),
2036 (uint8_t *)smb_buf(req->outbuf))) {
2037 goto error;
2039 TALLOC_FREE(req->outbuf);
2043 * We use the old request's vwv field to grab the next chained command
2044 * and offset into the chained fields.
2047 chain_cmd = CVAL(req->vwv+0, 0);
2048 chain_offset = SVAL(req->vwv+1, 0);
2050 if (chain_cmd == 0xff) {
2052 * End of chain, no more requests from the client. So ship the
2053 * replies.
2055 smb_setlen((char *)(req->chain_outbuf),
2056 talloc_get_size(req->chain_outbuf) - 4);
2058 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2059 true, req->seqnum+1,
2060 IS_CONN_ENCRYPTED(req->conn)
2061 ||req->encrypted,
2062 &req->pcd)) {
2063 exit_server_cleanly("chain_reply: srv_send_smb "
2064 "failed.");
2066 TALLOC_FREE(req->chain_outbuf);
2067 req->done = true;
2068 return;
2071 /* add a new perfcounter for this element of chain */
2072 SMB_PERFCOUNT_ADD(&req->pcd);
2073 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2074 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2077 * Check if the client tries to fool us. The request so far uses the
2078 * space to the end of the byte buffer in the request just
2079 * processed. The chain_offset can't point into that area. If that was
2080 * the case, we could end up with an endless processing of the chain,
2081 * we would always handle the same request.
2084 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2085 if (chain_offset < already_used) {
2086 goto error;
2090 * Next check: Make sure the chain offset does not point beyond the
2091 * overall smb request length.
2094 length_needed = chain_offset+1; /* wct */
2095 if (length_needed > smblen) {
2096 goto error;
2100 * Now comes the pointer magic. Goal here is to set up req->vwv and
2101 * req->buf correctly again to be able to call the subsequent
2102 * switch_message(). The chain offset (the former vwv[1]) points at
2103 * the new wct field.
2106 wct = CVAL(smb_base(req->inbuf), chain_offset);
2109 * Next consistency check: Make the new vwv array fits in the overall
2110 * smb request.
2113 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2114 if (length_needed > smblen) {
2115 goto error;
2117 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2120 * Now grab the new byte buffer....
2123 buflen = SVAL(vwv+wct, 0);
2126 * .. and check that it fits.
2129 length_needed += buflen;
2130 if (length_needed > smblen) {
2131 goto error;
2133 buf = (uint8_t *)(vwv+wct+1);
2135 req->cmd = chain_cmd;
2136 req->wct = wct;
2137 req->vwv = vwv;
2138 req->buflen = buflen;
2139 req->buf = buf;
2141 switch_message(chain_cmd, req, smblen);
2143 if (req->outbuf == NULL) {
2145 * This happens if the chained command has suspended itself or
2146 * if it has called srv_send_smb() itself.
2148 return;
2152 * We end up here if the chained command was not itself chained or
2153 * suspended, but for example a close() command. We now need to splice
2154 * the chained commands' outbuf into the already built up chain_outbuf
2155 * and ship the result.
2157 goto done;
2159 error:
2161 * We end up here if there's any error in the chain syntax. Report a
2162 * DOS error, just like Windows does.
2164 reply_force_doserror(req, ERRSRV, ERRerror);
2165 fixup_chain_error_packet(req);
2167 done:
2169 * This scary statement intends to set the
2170 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2171 * to the value req->outbuf carries
2173 SSVAL(req->chain_outbuf, smb_flg2,
2174 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2175 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2178 * Transfer the error codes from the subrequest to the main one
2180 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2181 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2183 if (!smb_splice_chain(&req->chain_outbuf,
2184 CVAL(req->outbuf, smb_com),
2185 CVAL(req->outbuf, smb_wct),
2186 (uint16_t *)(req->outbuf + smb_vwv),
2187 0, smb_buflen(req->outbuf),
2188 (uint8_t *)smb_buf(req->outbuf))) {
2189 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2191 TALLOC_FREE(req->outbuf);
2193 smb_setlen((char *)(req->chain_outbuf),
2194 talloc_get_size(req->chain_outbuf) - 4);
2196 show_msg((char *)(req->chain_outbuf));
2198 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2199 true, req->seqnum+1,
2200 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2201 &req->pcd)) {
2202 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2204 TALLOC_FREE(req->chain_outbuf);
2205 req->done = true;
2208 /****************************************************************************
2209 Check if services need reloading.
2210 ****************************************************************************/
2212 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2215 if (last_smb_conf_reload_time == 0) {
2216 last_smb_conf_reload_time = t;
2219 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2220 reload_services(sconn->msg_ctx, sconn->sock, True);
2221 last_smb_conf_reload_time = t;
2225 static bool fd_is_readable(int fd)
2227 int ret, revents;
2229 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2231 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2235 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2237 /* TODO: make write nonblocking */
2240 static void smbd_server_connection_read_handler(
2241 struct smbd_server_connection *conn, int fd)
2243 uint8_t *inbuf = NULL;
2244 size_t inbuf_len = 0;
2245 size_t unread_bytes = 0;
2246 bool encrypted = false;
2247 TALLOC_CTX *mem_ctx = talloc_tos();
2248 NTSTATUS status;
2249 uint32_t seqnum;
2251 bool from_client = (conn->sock == fd);
2253 if (from_client) {
2254 smbd_lock_socket(conn);
2256 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2257 DEBUG(10,("the echo listener was faster\n"));
2258 smbd_unlock_socket(conn);
2259 return;
2262 /* TODO: make this completely nonblocking */
2263 status = receive_smb_talloc(mem_ctx, conn,
2264 (char **)(void *)&inbuf,
2265 0, /* timeout */
2266 &unread_bytes,
2267 &encrypted,
2268 &inbuf_len, &seqnum,
2269 false /* trusted channel */);
2270 smbd_unlock_socket(conn);
2271 } else {
2272 /* TODO: make this completely nonblocking */
2273 status = receive_smb_talloc(mem_ctx, conn,
2274 (char **)(void *)&inbuf,
2275 0, /* timeout */
2276 &unread_bytes,
2277 &encrypted,
2278 &inbuf_len, &seqnum,
2279 true /* trusted channel */);
2282 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2283 goto process;
2285 if (NT_STATUS_IS_ERR(status)) {
2286 exit_server_cleanly("failed to receive smb request");
2288 if (!NT_STATUS_IS_OK(status)) {
2289 return;
2292 process:
2293 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2294 seqnum, encrypted, NULL);
2297 static void smbd_server_connection_handler(struct event_context *ev,
2298 struct fd_event *fde,
2299 uint16_t flags,
2300 void *private_data)
2302 struct smbd_server_connection *conn = talloc_get_type(private_data,
2303 struct smbd_server_connection);
2305 if (flags & EVENT_FD_WRITE) {
2306 smbd_server_connection_write_handler(conn);
2307 return;
2309 if (flags & EVENT_FD_READ) {
2310 smbd_server_connection_read_handler(conn, conn->sock);
2311 return;
2315 static void smbd_server_echo_handler(struct event_context *ev,
2316 struct fd_event *fde,
2317 uint16_t flags,
2318 void *private_data)
2320 struct smbd_server_connection *conn = talloc_get_type(private_data,
2321 struct smbd_server_connection);
2323 if (flags & EVENT_FD_WRITE) {
2324 smbd_server_connection_write_handler(conn);
2325 return;
2327 if (flags & EVENT_FD_READ) {
2328 smbd_server_connection_read_handler(
2329 conn, conn->smb1.echo_handler.trusted_fd);
2330 return;
2334 /****************************************************************************
2335 received when we should release a specific IP
2336 ****************************************************************************/
2337 static void release_ip(const char *ip, void *priv)
2339 const char *addr = (const char *)priv;
2340 const char *p = addr;
2342 if (strncmp("::ffff:", addr, 7) == 0) {
2343 p = addr + 7;
2346 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2347 /* we can't afford to do a clean exit - that involves
2348 database writes, which would potentially mean we
2349 are still running after the failover has finished -
2350 we have to get rid of this process ID straight
2351 away */
2352 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2353 ip));
2354 /* note we must exit with non-zero status so the unclean handler gets
2355 called in the parent, so that the brl database is tickled */
2356 _exit(1);
2360 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2361 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2363 struct smbd_server_connection *sconn = talloc_get_type_abort(
2364 private_data, struct smbd_server_connection);
2366 release_ip((char *)data->data, sconn->client_id.addr);
2369 #ifdef CLUSTER_SUPPORT
2370 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2371 struct sockaddr_storage *client)
2373 socklen_t length;
2374 length = sizeof(*server);
2375 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2376 return -1;
2378 length = sizeof(*client);
2379 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2380 return -1;
2382 return 0;
2384 #endif
2387 * Send keepalive packets to our client
2389 static bool keepalive_fn(const struct timeval *now, void *private_data)
2391 struct smbd_server_connection *sconn = smbd_server_conn;
2392 bool ret;
2394 if (sconn->using_smb2) {
2395 /* Don't do keepalives on an SMB2 connection. */
2396 return false;
2399 smbd_lock_socket(smbd_server_conn);
2400 ret = send_keepalive(sconn->sock);
2401 smbd_unlock_socket(smbd_server_conn);
2403 if (!ret) {
2404 char addr[INET6_ADDRSTRLEN];
2406 * Try and give an error message saying what
2407 * client failed.
2409 DEBUG(0, ("send_keepalive failed for client %s. "
2410 "Error %s - exiting\n",
2411 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2412 strerror(errno)));
2413 return False;
2415 return True;
2419 * Do the recurring check if we're idle
2421 static bool deadtime_fn(const struct timeval *now, void *private_data)
2423 struct smbd_server_connection *sconn =
2424 (struct smbd_server_connection *)private_data;
2426 if ((conn_num_open(sconn) == 0)
2427 || (conn_idle_all(sconn, now->tv_sec))) {
2428 DEBUG( 2, ( "Closing idle connection\n" ) );
2429 messaging_send(sconn->msg_ctx,
2430 messaging_server_id(sconn->msg_ctx),
2431 MSG_SHUTDOWN, &data_blob_null);
2432 return False;
2435 return True;
2439 * Do the recurring log file and smb.conf reload checks.
2442 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2444 struct smbd_server_connection *sconn = talloc_get_type_abort(
2445 private_data, struct smbd_server_connection);
2447 DEBUG(5, ("housekeeping\n"));
2449 change_to_root_user();
2451 /* update printer queue caches if necessary */
2452 update_monitored_printq_cache(sconn->msg_ctx);
2454 /* check if we need to reload services */
2455 check_reload(sconn, time_mono(NULL));
2457 /* Change machine password if neccessary. */
2458 attempt_machine_password_change();
2461 * Force a log file check.
2463 force_check_log_size();
2464 check_log_size();
2465 return true;
2468 static int create_unlink_tmp(const char *dir)
2470 char *fname;
2471 int fd;
2473 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2474 if (fname == NULL) {
2475 errno = ENOMEM;
2476 return -1;
2478 fd = mkstemp(fname);
2479 if (fd == -1) {
2480 TALLOC_FREE(fname);
2481 return -1;
2483 if (unlink(fname) == -1) {
2484 int sys_errno = errno;
2485 close(fd);
2486 TALLOC_FREE(fname);
2487 errno = sys_errno;
2488 return -1;
2490 TALLOC_FREE(fname);
2491 return fd;
2494 struct smbd_echo_state {
2495 struct tevent_context *ev;
2496 struct iovec *pending;
2497 struct smbd_server_connection *sconn;
2498 int parent_pipe;
2500 struct tevent_fd *parent_fde;
2502 struct tevent_fd *read_fde;
2503 struct tevent_req *write_req;
2506 static void smbd_echo_writer_done(struct tevent_req *req);
2508 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2510 int num_pending;
2512 if (state->write_req != NULL) {
2513 return;
2516 num_pending = talloc_array_length(state->pending);
2517 if (num_pending == 0) {
2518 return;
2521 state->write_req = writev_send(state, state->ev, NULL,
2522 state->parent_pipe, false,
2523 state->pending, num_pending);
2524 if (state->write_req == NULL) {
2525 DEBUG(1, ("writev_send failed\n"));
2526 exit(1);
2529 talloc_steal(state->write_req, state->pending);
2530 state->pending = NULL;
2532 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2533 state);
2536 static void smbd_echo_writer_done(struct tevent_req *req)
2538 struct smbd_echo_state *state = tevent_req_callback_data(
2539 req, struct smbd_echo_state);
2540 ssize_t written;
2541 int err;
2543 written = writev_recv(req, &err);
2544 TALLOC_FREE(req);
2545 state->write_req = NULL;
2546 if (written == -1) {
2547 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2548 exit(1);
2550 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2551 smbd_echo_activate_writer(state);
2554 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2555 uint32_t seqnum)
2557 struct smb_request req;
2558 uint16_t num_replies;
2559 size_t out_len;
2560 char *outbuf;
2561 bool ok;
2563 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2564 DEBUG(10, ("Got netbios keepalive\n"));
2566 * Just swallow it
2568 return true;
2571 if (inbuf_len < smb_size) {
2572 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2573 return false;
2575 if (!valid_smb_header(inbuf)) {
2576 DEBUG(10, ("Got invalid SMB header\n"));
2577 return false;
2580 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2581 seqnum)) {
2582 return false;
2584 req.inbuf = inbuf;
2586 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2587 smb_messages[req.cmd].name
2588 ? smb_messages[req.cmd].name : "unknown"));
2590 if (req.cmd != SMBecho) {
2591 return false;
2593 if (req.wct < 1) {
2594 return false;
2597 num_replies = SVAL(req.vwv+0, 0);
2598 if (num_replies != 1) {
2599 /* Not a Windows "Hey, you're still there?" request */
2600 return false;
2603 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2604 1, req.buflen)) {
2605 DEBUG(10, ("create_outbuf failed\n"));
2606 return false;
2608 req.outbuf = (uint8_t *)outbuf;
2610 SSVAL(req.outbuf, smb_vwv0, num_replies);
2612 if (req.buflen > 0) {
2613 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2616 out_len = smb_len(req.outbuf) + 4;
2618 ok = srv_send_smb(req.sconn,
2619 (char *)outbuf,
2620 true, seqnum+1,
2621 false, &req.pcd);
2622 TALLOC_FREE(outbuf);
2623 if (!ok) {
2624 exit(1);
2627 return true;
2630 static void smbd_echo_exit(struct tevent_context *ev,
2631 struct tevent_fd *fde, uint16_t flags,
2632 void *private_data)
2634 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2635 exit(0);
2638 static void smbd_echo_reader(struct tevent_context *ev,
2639 struct tevent_fd *fde, uint16_t flags,
2640 void *private_data)
2642 struct smbd_echo_state *state = talloc_get_type_abort(
2643 private_data, struct smbd_echo_state);
2644 struct smbd_server_connection *sconn = state->sconn;
2645 size_t unread, num_pending;
2646 NTSTATUS status;
2647 struct iovec *tmp;
2648 size_t iov_len;
2649 uint32_t seqnum = 0;
2650 bool reply;
2651 bool ok;
2652 bool encrypted = false;
2654 smb_msleep(1000);
2656 ok = smbd_lock_socket_internal(sconn);
2657 if (!ok) {
2658 DEBUG(0, ("%s: failed to lock socket\n",
2659 __location__));
2660 exit(1);
2663 if (!fd_is_readable(sconn->sock)) {
2664 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2665 (int)sys_getpid()));
2666 ok = smbd_unlock_socket_internal(sconn);
2667 if (!ok) {
2668 DEBUG(1, ("%s: failed to unlock socket in\n",
2669 __location__));
2670 exit(1);
2672 return;
2675 num_pending = talloc_array_length(state->pending);
2676 tmp = talloc_realloc(state, state->pending, struct iovec,
2677 num_pending+1);
2678 if (tmp == NULL) {
2679 DEBUG(1, ("talloc_realloc failed\n"));
2680 exit(1);
2682 state->pending = tmp;
2684 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2686 status = receive_smb_talloc(state->pending, sconn,
2687 (char **)(void *)&state->pending[num_pending].iov_base,
2688 0 /* timeout */,
2689 &unread,
2690 &encrypted,
2691 &iov_len,
2692 &seqnum,
2693 false /* trusted_channel*/);
2694 if (!NT_STATUS_IS_OK(status)) {
2695 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2696 (int)sys_getpid(), nt_errstr(status)));
2697 exit(1);
2699 state->pending[num_pending].iov_len = iov_len;
2701 ok = smbd_unlock_socket_internal(sconn);
2702 if (!ok) {
2703 DEBUG(1, ("%s: failed to unlock socket in\n",
2704 __location__));
2705 exit(1);
2708 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2709 state->pending[num_pending].iov_len,
2710 seqnum);
2711 if (reply) {
2712 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2713 /* no check, shrinking by some bytes does not fail */
2714 state->pending = talloc_realloc(state, state->pending,
2715 struct iovec,
2716 num_pending);
2717 return;
2720 if (state->pending[num_pending].iov_len >= smb_size) {
2722 * place the seqnum in the packet so that the main process
2723 * can reply with signing
2725 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2726 smb_ss_field, seqnum);
2727 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2728 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2731 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2732 smbd_echo_activate_writer(state);
2735 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2736 int parent_pipe)
2738 struct smbd_echo_state *state;
2740 state = talloc_zero(sconn, struct smbd_echo_state);
2741 if (state == NULL) {
2742 DEBUG(1, ("talloc failed\n"));
2743 return;
2745 state->sconn = sconn;
2746 state->parent_pipe = parent_pipe;
2747 state->ev = s3_tevent_context_init(state);
2748 if (state->ev == NULL) {
2749 DEBUG(1, ("tevent_context_init failed\n"));
2750 TALLOC_FREE(state);
2751 return;
2753 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2754 TEVENT_FD_READ, smbd_echo_exit,
2755 state);
2756 if (state->parent_fde == NULL) {
2757 DEBUG(1, ("tevent_add_fd failed\n"));
2758 TALLOC_FREE(state);
2759 return;
2761 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2762 TEVENT_FD_READ, smbd_echo_reader,
2763 state);
2764 if (state->read_fde == NULL) {
2765 DEBUG(1, ("tevent_add_fd failed\n"));
2766 TALLOC_FREE(state);
2767 return;
2770 while (true) {
2771 if (tevent_loop_once(state->ev) == -1) {
2772 DEBUG(1, ("tevent_loop_once failed: %s\n",
2773 strerror(errno)));
2774 break;
2777 TALLOC_FREE(state);
2781 * Handle SMBecho requests in a forked child process
2783 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2785 int listener_pipe[2];
2786 int res;
2787 pid_t child;
2789 res = pipe(listener_pipe);
2790 if (res == -1) {
2791 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2792 return false;
2794 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2795 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2796 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2797 goto fail;
2800 child = sys_fork();
2801 if (child == 0) {
2802 NTSTATUS status;
2804 close(listener_pipe[0]);
2805 set_blocking(listener_pipe[1], false);
2807 status = reinit_after_fork(sconn->msg_ctx,
2808 smbd_event_context(),
2809 procid_self(), false);
2810 if (!NT_STATUS_IS_OK(status)) {
2811 DEBUG(1, ("reinit_after_fork failed: %s\n",
2812 nt_errstr(status)));
2813 exit(1);
2815 smbd_echo_loop(sconn, listener_pipe[1]);
2816 exit(0);
2818 close(listener_pipe[1]);
2819 listener_pipe[1] = -1;
2820 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2822 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2825 * Without smb signing this is the same as the normal smbd
2826 * listener. This needs to change once signing comes in.
2828 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2829 sconn,
2830 sconn->smb1.echo_handler.trusted_fd,
2831 EVENT_FD_READ,
2832 smbd_server_echo_handler,
2833 sconn);
2834 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2835 DEBUG(1, ("event_add_fd failed\n"));
2836 goto fail;
2839 return true;
2841 fail:
2842 if (listener_pipe[0] != -1) {
2843 close(listener_pipe[0]);
2845 if (listener_pipe[1] != -1) {
2846 close(listener_pipe[1]);
2848 sconn->smb1.echo_handler.trusted_fd = -1;
2849 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2850 close(sconn->smb1.echo_handler.socket_lock_fd);
2852 sconn->smb1.echo_handler.trusted_fd = -1;
2853 sconn->smb1.echo_handler.socket_lock_fd = -1;
2854 return false;
2857 #if CLUSTER_SUPPORT
2859 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2860 struct sockaddr_storage *srv,
2861 struct sockaddr_storage *clnt)
2863 struct ctdbd_connection *cconn;
2864 char tmp_addr[INET6_ADDRSTRLEN];
2865 char *addr;
2867 cconn = messaging_ctdbd_connection();
2868 if (cconn == NULL) {
2869 return NT_STATUS_NO_MEMORY;
2872 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2873 addr = talloc_strdup(cconn, tmp_addr);
2874 if (addr == NULL) {
2875 return NT_STATUS_NO_MEMORY;
2877 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2880 #endif
2882 /****************************************************************************
2883 Process commands from the client
2884 ****************************************************************************/
2886 void smbd_process(struct smbd_server_connection *sconn)
2888 TALLOC_CTX *frame = talloc_stackframe();
2889 struct sockaddr_storage ss;
2890 struct sockaddr *sa = NULL;
2891 socklen_t sa_socklen;
2892 struct tsocket_address *local_address = NULL;
2893 struct tsocket_address *remote_address = NULL;
2894 const char *remaddr = NULL;
2895 int ret;
2897 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2898 !lp_async_smb_echo_handler()) {
2900 * We're not making the desion here,
2901 * we're just allowing the client
2902 * to decide between SMB1 and SMB2
2903 * with the first negprot
2904 * packet.
2906 sconn->using_smb2 = true;
2909 /* Ensure child is set to blocking mode */
2910 set_blocking(sconn->sock,True);
2912 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2913 set_socket_options(sconn->sock, lp_socket_options());
2915 sa = (struct sockaddr *)(void *)&ss;
2916 sa_socklen = sizeof(ss);
2917 ret = getpeername(sconn->sock, sa, &sa_socklen);
2918 if (ret != 0) {
2919 int level = (errno == ENOTCONN)?2:0;
2920 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2921 exit_server_cleanly("getpeername() failed.\n");
2923 ret = tsocket_address_bsd_from_sockaddr(sconn,
2924 sa, sa_socklen,
2925 &remote_address);
2926 if (ret != 0) {
2927 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2928 __location__, strerror(errno)));
2929 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2932 sa = (struct sockaddr *)(void *)&ss;
2933 sa_socklen = sizeof(ss);
2934 ret = getsockname(sconn->sock, sa, &sa_socklen);
2935 if (ret != 0) {
2936 int level = (errno == ENOTCONN)?2:0;
2937 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2938 exit_server_cleanly("getsockname() failed.\n");
2940 ret = tsocket_address_bsd_from_sockaddr(sconn,
2941 sa, sa_socklen,
2942 &local_address);
2943 if (ret != 0) {
2944 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2945 __location__, strerror(errno)));
2946 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2949 sconn->local_address = local_address;
2950 sconn->remote_address = remote_address;
2952 if (tsocket_address_is_inet(remote_address, "ip")) {
2953 remaddr = tsocket_address_inet_addr_string(
2954 sconn->remote_address,
2955 talloc_tos());
2956 if (remaddr == NULL) {
2959 } else {
2960 remaddr = "0.0.0.0";
2963 /* this is needed so that we get decent entries
2964 in smbstatus for port 445 connects */
2965 set_remote_machine_name(remaddr, false);
2966 reload_services(sconn->msg_ctx, sconn->sock, true);
2969 * Before the first packet, check the global hosts allow/ hosts deny
2970 * parameters before doing any parsing of packets passed to us by the
2971 * client. This prevents attacks on our parsing code from hosts not in
2972 * the hosts allow list.
2975 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2976 sconn->client_id.name,
2977 sconn->client_id.addr)) {
2979 * send a negative session response "not listening on calling
2980 * name"
2982 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2983 DEBUG( 1, ("Connection denied from %s to %s\n",
2984 tsocket_address_string(remote_address, talloc_tos()),
2985 tsocket_address_string(local_address, talloc_tos())));
2986 (void)srv_send_smb(sconn,(char *)buf, false,
2987 0, false, NULL);
2988 exit_server_cleanly("connection denied");
2991 DEBUG(10, ("Connection allowed from %s to %s\n",
2992 tsocket_address_string(remote_address, talloc_tos()),
2993 tsocket_address_string(local_address, talloc_tos())));
2995 init_modules();
2997 smb_perfcount_init();
2999 if (!init_account_policy()) {
3000 exit_server("Could not open account policy tdb.\n");
3003 if (*lp_rootdir()) {
3004 if (chroot(lp_rootdir()) != 0) {
3005 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3006 exit_server("Failed to chroot()");
3008 if (chdir("/") == -1) {
3009 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3010 exit_server("Failed to chroot()");
3012 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3015 if (!srv_init_signing(sconn)) {
3016 exit_server("Failed to init smb_signing");
3019 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3020 exit_server("Failed to fork echo handler");
3023 /* Setup oplocks */
3024 if (!init_oplocks(sconn->msg_ctx))
3025 exit_server("Failed to init oplocks");
3027 /* register our message handlers */
3028 messaging_register(sconn->msg_ctx, NULL,
3029 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3030 messaging_register(sconn->msg_ctx, sconn,
3031 MSG_SMB_RELEASE_IP, msg_release_ip);
3032 messaging_register(sconn->msg_ctx, NULL,
3033 MSG_SMB_CLOSE_FILE, msg_close_file);
3036 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3037 * MSGs to all child processes
3039 messaging_deregister(sconn->msg_ctx,
3040 MSG_DEBUG, NULL);
3041 messaging_register(sconn->msg_ctx, NULL,
3042 MSG_DEBUG, debug_message);
3044 if ((lp_keepalive() != 0)
3045 && !(event_add_idle(smbd_event_context(), NULL,
3046 timeval_set(lp_keepalive(), 0),
3047 "keepalive", keepalive_fn,
3048 NULL))) {
3049 DEBUG(0, ("Could not add keepalive event\n"));
3050 exit(1);
3053 if (!(event_add_idle(smbd_event_context(), NULL,
3054 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3055 "deadtime", deadtime_fn, sconn))) {
3056 DEBUG(0, ("Could not add deadtime event\n"));
3057 exit(1);
3060 if (!(event_add_idle(smbd_event_context(), NULL,
3061 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3062 "housekeeping", housekeeping_fn, sconn))) {
3063 DEBUG(0, ("Could not add housekeeping event\n"));
3064 exit(1);
3067 #ifdef CLUSTER_SUPPORT
3069 if (lp_clustering()) {
3071 * We need to tell ctdb about our client's TCP
3072 * connection, so that for failover ctdbd can send
3073 * tickle acks, triggering a reconnection by the
3074 * client.
3077 struct sockaddr_storage srv, clnt;
3079 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3080 NTSTATUS status;
3081 status = smbd_register_ips(sconn, &srv, &clnt);
3082 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3084 nt_errstr(status)));
3086 } else
3088 DEBUG(0,("Unable to get tcp info for "
3089 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3090 strerror(errno)));
3094 #endif
3096 sconn->nbt.got_session = false;
3098 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3100 sconn->smb1.sessions.done_sesssetup = false;
3101 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3102 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3103 /* users from session setup */
3104 sconn->smb1.sessions.session_userlist = NULL;
3105 /* workgroup from session setup. */
3106 sconn->smb1.sessions.session_workgroup = NULL;
3107 /* this holds info on user ids that are already validated for this VC */
3108 sconn->smb1.sessions.validated_users = NULL;
3109 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3110 sconn->smb1.sessions.num_validated_vuids = 0;
3112 conn_init(sconn);
3113 if (!init_dptrs(sconn)) {
3114 exit_server("init_dptrs() failed");
3117 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3118 sconn,
3119 sconn->sock,
3120 EVENT_FD_READ,
3121 smbd_server_connection_handler,
3122 sconn);
3123 if (!sconn->smb1.fde) {
3124 exit_server("failed to create smbd_server_connection fde");
3127 TALLOC_FREE(frame);
3129 while (True) {
3130 NTSTATUS status;
3132 frame = talloc_stackframe_pool(8192);
3134 errno = 0;
3136 status = smbd_server_connection_loop_once(sconn);
3137 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3138 !NT_STATUS_IS_OK(status)) {
3139 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3140 " exiting\n", nt_errstr(status)));
3141 break;
3144 TALLOC_FREE(frame);
3147 exit_server_cleanly(NULL);
3150 bool req_is_in_chain(struct smb_request *req)
3152 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3154 * We're right now handling a subsequent request, so we must
3155 * be in a chain
3157 return true;
3160 if (!is_andx_req(req->cmd)) {
3161 return false;
3164 if (req->wct < 2) {
3166 * Okay, an illegal request, but definitely not chained :-)
3168 return false;
3171 return (CVAL(req->vwv+0, 0) != 0xFF);