s3: Cope with EINTR in smbd_[un]lock_socket
[Samba/gbeck.git] / source3 / smbd / process.c
blob99c98e3a377dd3f1b40b787bc31b9f9c73534b93
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"
29 extern bool global_machine_password_needs_changing;
31 static void construct_reply_common(struct smb_request *req, const char *inbuf,
32 char *outbuf);
33 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
35 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
37 bool ok;
39 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
40 return true;
43 sconn->smb1.echo_handler.ref_count++;
45 if (sconn->smb1.echo_handler.ref_count > 1) {
46 return true;
49 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
51 do {
52 ok = fcntl_lock(
53 sconn->smb1.echo_handler.socket_lock_fd,
54 SMB_F_SETLKW, 0, 0, F_WRLCK);
55 } while (!ok && (errno == EINTR));
57 if (!ok) {
58 return false;
61 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
63 return true;
66 void smbd_lock_socket(struct smbd_server_connection *sconn)
68 if (!smbd_lock_socket_internal(sconn)) {
69 exit_server_cleanly("failed to lock socket");
73 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
75 bool ok;
77 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
78 return true;
81 sconn->smb1.echo_handler.ref_count--;
83 if (sconn->smb1.echo_handler.ref_count > 0) {
84 return true;
87 do {
88 ok = fcntl_lock(
89 sconn->smb1.echo_handler.socket_lock_fd,
90 SMB_F_SETLKW, 0, 0, F_UNLCK);
91 } while (!ok && (errno == EINTR));
93 if (!ok) {
94 return false;
97 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
99 return true;
102 void smbd_unlock_socket(struct smbd_server_connection *sconn)
104 if (!smbd_unlock_socket_internal(sconn)) {
105 exit_server_cleanly("failed to unlock socket");
109 /* Accessor function for smb_read_error for smbd functions. */
111 /****************************************************************************
112 Send an smb to a fd.
113 ****************************************************************************/
115 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
116 bool do_signing, uint32_t seqnum,
117 bool do_encrypt,
118 struct smb_perfcount_data *pcd)
120 size_t len = 0;
121 size_t nwritten=0;
122 ssize_t ret;
123 char *buf_out = buffer;
125 smbd_lock_socket(sconn);
127 if (do_signing) {
128 /* Sign the outgoing packet if required. */
129 srv_calculate_sign_mac(sconn, buf_out, seqnum);
132 if (do_encrypt) {
133 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
134 if (!NT_STATUS_IS_OK(status)) {
135 DEBUG(0, ("send_smb: SMB encryption failed "
136 "on outgoing packet! Error %s\n",
137 nt_errstr(status) ));
138 goto out;
142 len = smb_len(buf_out) + 4;
144 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
145 if (ret <= 0) {
147 char addr[INET6_ADDRSTRLEN];
149 * Try and give an error message saying what
150 * client failed.
152 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
153 (int)sys_getpid(), (int)len,
154 get_peer_addr(sconn->sock, addr, sizeof(addr)),
155 (int)ret, strerror(errno) ));
157 srv_free_enc_buffer(buf_out);
158 goto out;
161 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
162 srv_free_enc_buffer(buf_out);
163 out:
164 SMB_PERFCOUNT_END(pcd);
166 smbd_unlock_socket(sconn);
167 return true;
170 /*******************************************************************
171 Setup the word count and byte count for a smb message.
172 ********************************************************************/
174 int srv_set_message(char *buf,
175 int num_words,
176 int num_bytes,
177 bool zero)
179 if (zero && (num_words || num_bytes)) {
180 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
182 SCVAL(buf,smb_wct,num_words);
183 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
184 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
185 return (smb_size + num_words*2 + num_bytes);
188 static bool valid_smb_header(const uint8_t *inbuf)
190 if (is_encrypted_packet(inbuf)) {
191 return true;
194 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
195 * but it just looks weird to call strncmp for this one.
197 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
200 /* Socket functions for smbd packet processing. */
202 static bool valid_packet_size(size_t len)
205 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
206 * of header. Don't print the error if this fits.... JRA.
209 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
210 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
211 (unsigned long)len));
212 return false;
214 return true;
217 static NTSTATUS read_packet_remainder(int fd, char *buffer,
218 unsigned int timeout, ssize_t len)
220 NTSTATUS status;
222 if (len <= 0) {
223 return NT_STATUS_OK;
226 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
227 if (!NT_STATUS_IS_OK(status)) {
228 char addr[INET6_ADDRSTRLEN];
229 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
230 "error = %s.\n",
231 get_peer_addr(fd, addr, sizeof(addr)),
232 nt_errstr(status)));
234 return status;
237 /****************************************************************************
238 Attempt a zerocopy writeX read. We know here that len > smb_size-4
239 ****************************************************************************/
242 * Unfortunately, earlier versions of smbclient/libsmbclient
243 * don't send this "standard" writeX header. I've fixed this
244 * for 3.2 but we'll use the old method with earlier versions.
245 * Windows and CIFSFS at least use this standard size. Not
246 * sure about MacOSX.
249 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
250 (2*14) + /* word count (including bcc) */ \
251 1 /* pad byte */)
253 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
254 const char lenbuf[4],
255 struct smbd_server_connection *sconn,
256 char **buffer,
257 unsigned int timeout,
258 size_t *p_unread,
259 size_t *len_ret)
261 /* Size of a WRITEX call (+4 byte len). */
262 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
263 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
264 ssize_t toread;
265 NTSTATUS status;
267 memcpy(writeX_header, lenbuf, 4);
269 status = read_fd_with_timeout(
270 sconn->sock, writeX_header + 4,
271 STANDARD_WRITE_AND_X_HEADER_SIZE,
272 STANDARD_WRITE_AND_X_HEADER_SIZE,
273 timeout, NULL);
275 if (!NT_STATUS_IS_OK(status)) {
276 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
277 "error = %s.\n", sconn->client_id.addr,
278 nt_errstr(status)));
279 return status;
283 * Ok - now try and see if this is a possible
284 * valid writeX call.
287 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
289 * If the data offset is beyond what
290 * we've read, drain the extra bytes.
292 uint16_t doff = SVAL(writeX_header,smb_vwv11);
293 ssize_t newlen;
295 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
296 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
297 if (drain_socket(sconn->sock, drain) != drain) {
298 smb_panic("receive_smb_raw_talloc_partial_read:"
299 " failed to drain pending bytes");
301 } else {
302 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
305 /* Spoof down the length and null out the bcc. */
306 set_message_bcc(writeX_header, 0);
307 newlen = smb_len(writeX_header);
309 /* Copy the header we've written. */
311 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
312 writeX_header,
313 sizeof(writeX_header));
315 if (*buffer == NULL) {
316 DEBUG(0, ("Could not allocate inbuf of length %d\n",
317 (int)sizeof(writeX_header)));
318 return NT_STATUS_NO_MEMORY;
321 /* Work out the remaining bytes. */
322 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
323 *len_ret = newlen + 4;
324 return NT_STATUS_OK;
327 if (!valid_packet_size(len)) {
328 return NT_STATUS_INVALID_PARAMETER;
332 * Not a valid writeX call. Just do the standard
333 * talloc and return.
336 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
338 if (*buffer == NULL) {
339 DEBUG(0, ("Could not allocate inbuf of length %d\n",
340 (int)len+4));
341 return NT_STATUS_NO_MEMORY;
344 /* Copy in what we already read. */
345 memcpy(*buffer,
346 writeX_header,
347 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
348 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
350 if(toread > 0) {
351 status = read_packet_remainder(
352 sconn->sock,
353 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
354 timeout, toread);
356 if (!NT_STATUS_IS_OK(status)) {
357 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
358 nt_errstr(status)));
359 return status;
363 *len_ret = len + 4;
364 return NT_STATUS_OK;
367 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
368 struct smbd_server_connection *sconn,
369 char **buffer, unsigned int timeout,
370 size_t *p_unread, size_t *plen)
372 char lenbuf[4];
373 size_t len;
374 int min_recv_size = lp_min_receive_file_size();
375 NTSTATUS status;
377 *p_unread = 0;
379 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
380 &len);
381 if (!NT_STATUS_IS_OK(status)) {
382 return status;
385 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
386 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
387 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
388 !srv_is_signing_active(sconn) &&
389 sconn->smb1.echo_handler.trusted_fde == NULL) {
391 return receive_smb_raw_talloc_partial_read(
392 mem_ctx, lenbuf, sconn, buffer, timeout,
393 p_unread, plen);
396 if (!valid_packet_size(len)) {
397 return NT_STATUS_INVALID_PARAMETER;
401 * The +4 here can't wrap, we've checked the length above already.
404 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
406 if (*buffer == NULL) {
407 DEBUG(0, ("Could not allocate inbuf of length %d\n",
408 (int)len+4));
409 return NT_STATUS_NO_MEMORY;
412 memcpy(*buffer, lenbuf, sizeof(lenbuf));
414 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
415 if (!NT_STATUS_IS_OK(status)) {
416 return status;
419 *plen = len + 4;
420 return NT_STATUS_OK;
423 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
424 struct smbd_server_connection *sconn,
425 char **buffer, unsigned int timeout,
426 size_t *p_unread, bool *p_encrypted,
427 size_t *p_len,
428 uint32_t *seqnum,
429 bool trusted_channel)
431 size_t len = 0;
432 NTSTATUS status;
434 *p_encrypted = false;
436 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
437 p_unread, &len);
438 if (!NT_STATUS_IS_OK(status)) {
439 DEBUG(1, ("read_smb_length_return_keepalive failed for "
440 "client %s read error = %s.\n",
441 sconn->client_id.addr, nt_errstr(status)));
442 return status;
445 if (is_encrypted_packet((uint8_t *)*buffer)) {
446 status = srv_decrypt_buffer(*buffer);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
449 "incoming packet! Error %s\n",
450 nt_errstr(status) ));
451 return status;
453 *p_encrypted = true;
456 /* Check the incoming SMB signature. */
457 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
458 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
459 "incoming packet!\n"));
460 return NT_STATUS_INVALID_NETWORK_RESPONSE;
463 *p_len = len;
464 return NT_STATUS_OK;
468 * Initialize a struct smb_request from an inbuf
471 static bool init_smb_request(struct smb_request *req,
472 struct smbd_server_connection *sconn,
473 const uint8 *inbuf,
474 size_t unread_bytes, bool encrypted,
475 uint32_t seqnum)
477 size_t req_size = smb_len(inbuf) + 4;
478 /* Ensure we have at least smb_size bytes. */
479 if (req_size < smb_size) {
480 DEBUG(0,("init_smb_request: invalid request size %u\n",
481 (unsigned int)req_size ));
482 return false;
484 req->cmd = CVAL(inbuf, smb_com);
485 req->flags2 = SVAL(inbuf, smb_flg2);
486 req->smbpid = SVAL(inbuf, smb_pid);
487 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
488 req->seqnum = seqnum;
489 req->vuid = SVAL(inbuf, smb_uid);
490 req->tid = SVAL(inbuf, smb_tid);
491 req->wct = CVAL(inbuf, smb_wct);
492 req->vwv = (uint16_t *)(inbuf+smb_vwv);
493 req->buflen = smb_buflen(inbuf);
494 req->buf = (const uint8_t *)smb_buf(inbuf);
495 req->unread_bytes = unread_bytes;
496 req->encrypted = encrypted;
497 req->sconn = sconn;
498 req->conn = conn_find(sconn,req->tid);
499 req->chain_fsp = NULL;
500 req->chain_outbuf = NULL;
501 req->done = false;
502 req->smb2req = NULL;
503 smb_init_perfcount_data(&req->pcd);
505 /* Ensure we have at least wct words and 2 bytes of bcc. */
506 if (smb_size + req->wct*2 > req_size) {
507 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
508 (unsigned int)req->wct,
509 (unsigned int)req_size));
510 return false;
512 /* Ensure bcc is correct. */
513 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
514 DEBUG(0,("init_smb_request: invalid bcc number %u "
515 "(wct = %u, size %u)\n",
516 (unsigned int)req->buflen,
517 (unsigned int)req->wct,
518 (unsigned int)req_size));
519 return false;
522 req->outbuf = NULL;
523 return true;
526 static void process_smb(struct smbd_server_connection *conn,
527 uint8_t *inbuf, size_t nread, size_t unread_bytes,
528 uint32_t seqnum, bool encrypted,
529 struct smb_perfcount_data *deferred_pcd);
531 static void smbd_deferred_open_timer(struct event_context *ev,
532 struct timed_event *te,
533 struct timeval _tval,
534 void *private_data)
536 struct pending_message_list *msg = talloc_get_type(private_data,
537 struct pending_message_list);
538 TALLOC_CTX *mem_ctx = talloc_tos();
539 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
540 uint8_t *inbuf;
542 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
543 msg->buf.length);
544 if (inbuf == NULL) {
545 exit_server("smbd_deferred_open_timer: talloc failed\n");
546 return;
549 /* We leave this message on the queue so the open code can
550 know this is a retry. */
551 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
552 (unsigned long long)mid ));
554 /* Mark the message as processed so this is not
555 * re-processed in error. */
556 msg->processed = true;
558 process_smb(smbd_server_conn, inbuf,
559 msg->buf.length, 0,
560 msg->seqnum, msg->encrypted, &msg->pcd);
562 /* If it's still there and was processed, remove it. */
563 msg = get_deferred_open_message_smb(mid);
564 if (msg && msg->processed) {
565 remove_deferred_open_message_smb(mid);
569 /****************************************************************************
570 Function to push a message onto the tail of a linked list of smb messages ready
571 for processing.
572 ****************************************************************************/
574 static bool push_queued_message(struct smb_request *req,
575 struct timeval request_time,
576 struct timeval end_time,
577 char *private_data, size_t private_len)
579 int msg_len = smb_len(req->inbuf) + 4;
580 struct pending_message_list *msg;
582 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
584 if(msg == NULL) {
585 DEBUG(0,("push_message: malloc fail (1)\n"));
586 return False;
589 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
590 if(msg->buf.data == NULL) {
591 DEBUG(0,("push_message: malloc fail (2)\n"));
592 TALLOC_FREE(msg);
593 return False;
596 msg->request_time = request_time;
597 msg->seqnum = req->seqnum;
598 msg->encrypted = req->encrypted;
599 msg->processed = false;
600 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
602 if (private_data) {
603 msg->private_data = data_blob_talloc(msg, private_data,
604 private_len);
605 if (msg->private_data.data == NULL) {
606 DEBUG(0,("push_message: malloc fail (3)\n"));
607 TALLOC_FREE(msg);
608 return False;
612 msg->te = event_add_timed(smbd_event_context(),
613 msg,
614 end_time,
615 smbd_deferred_open_timer,
616 msg);
617 if (!msg->te) {
618 DEBUG(0,("push_message: event_add_timed failed\n"));
619 TALLOC_FREE(msg);
620 return false;
623 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
625 DEBUG(10,("push_message: pushed message length %u on "
626 "deferred_open_queue\n", (unsigned int)msg_len));
628 return True;
631 /****************************************************************************
632 Function to delete a sharing violation open message by mid.
633 ****************************************************************************/
635 void remove_deferred_open_message_smb(uint64_t mid)
637 struct pending_message_list *pml;
639 if (smbd_server_conn->using_smb2) {
640 remove_deferred_open_message_smb2(smbd_server_conn, mid);
641 return;
644 for (pml = deferred_open_queue; pml; pml = pml->next) {
645 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
646 DEBUG(10,("remove_deferred_open_message_smb: "
647 "deleting mid %llu len %u\n",
648 (unsigned long long)mid,
649 (unsigned int)pml->buf.length ));
650 DLIST_REMOVE(deferred_open_queue, pml);
651 TALLOC_FREE(pml);
652 return;
657 /****************************************************************************
658 Move a sharing violation open retry message to the front of the list and
659 schedule it for immediate processing.
660 ****************************************************************************/
662 void schedule_deferred_open_message_smb(uint64_t mid)
664 struct pending_message_list *pml;
665 int i = 0;
667 if (smbd_server_conn->using_smb2) {
668 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
669 return;
672 for (pml = deferred_open_queue; pml; pml = pml->next) {
673 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
675 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
676 "msg_mid = %llu\n",
677 i++,
678 (unsigned long long)msg_mid ));
680 if (mid == msg_mid) {
681 struct timed_event *te;
683 if (pml->processed) {
684 /* A processed message should not be
685 * rescheduled. */
686 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
687 "message mid %llu was already processed\n",
688 (unsigned long long)msg_mid ));
689 continue;
692 DEBUG(10,("schedule_deferred_open_message_smb: "
693 "scheduling mid %llu\n",
694 (unsigned long long)mid ));
696 te = event_add_timed(smbd_event_context(),
697 pml,
698 timeval_zero(),
699 smbd_deferred_open_timer,
700 pml);
701 if (!te) {
702 DEBUG(10,("schedule_deferred_open_message_smb: "
703 "event_add_timed() failed, "
704 "skipping mid %llu\n",
705 (unsigned long long)msg_mid ));
708 TALLOC_FREE(pml->te);
709 pml->te = te;
710 DLIST_PROMOTE(deferred_open_queue, pml);
711 return;
715 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
716 "find message mid %llu\n",
717 (unsigned long long)mid ));
720 /****************************************************************************
721 Return true if this mid is on the deferred queue and was not yet processed.
722 ****************************************************************************/
724 bool open_was_deferred(uint64_t mid)
726 struct pending_message_list *pml;
728 if (smbd_server_conn->using_smb2) {
729 return open_was_deferred_smb2(smbd_server_conn, mid);
732 for (pml = deferred_open_queue; pml; pml = pml->next) {
733 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
734 return True;
737 return False;
740 /****************************************************************************
741 Return the message queued by this mid.
742 ****************************************************************************/
744 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
746 struct pending_message_list *pml;
748 for (pml = deferred_open_queue; pml; pml = pml->next) {
749 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
750 return pml;
753 return NULL;
756 /****************************************************************************
757 Get the state data queued by this mid.
758 ****************************************************************************/
760 bool get_deferred_open_message_state(struct smb_request *smbreq,
761 struct timeval *p_request_time,
762 void **pp_state)
764 struct pending_message_list *pml;
766 if (smbd_server_conn->using_smb2) {
767 return get_deferred_open_message_state_smb2(smbreq->smb2req,
768 p_request_time,
769 pp_state);
772 pml = get_deferred_open_message_smb(smbreq->mid);
773 if (!pml) {
774 return false;
776 if (p_request_time) {
777 *p_request_time = pml->request_time;
779 if (pp_state) {
780 *pp_state = (void *)pml->private_data.data;
782 return true;
785 /****************************************************************************
786 Function to push a deferred open smb message onto a linked list of local smb
787 messages ready for processing.
788 ****************************************************************************/
790 bool push_deferred_open_message_smb(struct smb_request *req,
791 struct timeval request_time,
792 struct timeval timeout,
793 struct file_id id,
794 char *private_data, size_t priv_len)
796 struct timeval end_time;
798 if (req->smb2req) {
799 return push_deferred_open_message_smb2(req->smb2req,
800 request_time,
801 timeout,
803 private_data,
804 priv_len);
807 if (req->unread_bytes) {
808 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
809 "unread_bytes = %u\n",
810 (unsigned int)req->unread_bytes ));
811 smb_panic("push_deferred_open_message_smb: "
812 "logic error unread_bytes != 0" );
815 end_time = timeval_sum(&request_time, &timeout);
817 DEBUG(10,("push_deferred_open_message_smb: pushing message "
818 "len %u mid %llu timeout time [%u.%06u]\n",
819 (unsigned int) smb_len(req->inbuf)+4,
820 (unsigned long long)req->mid,
821 (unsigned int)end_time.tv_sec,
822 (unsigned int)end_time.tv_usec));
824 return push_queued_message(req, request_time, end_time,
825 private_data, priv_len);
828 struct idle_event {
829 struct timed_event *te;
830 struct timeval interval;
831 char *name;
832 bool (*handler)(const struct timeval *now, void *private_data);
833 void *private_data;
836 static void smbd_idle_event_handler(struct event_context *ctx,
837 struct timed_event *te,
838 struct timeval now,
839 void *private_data)
841 struct idle_event *event =
842 talloc_get_type_abort(private_data, struct idle_event);
844 TALLOC_FREE(event->te);
846 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
847 event->name, event->te));
849 if (!event->handler(&now, event->private_data)) {
850 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
851 event->name, event->te));
852 /* Don't repeat, delete ourselves */
853 TALLOC_FREE(event);
854 return;
857 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
858 event->name, event->te));
860 event->te = event_add_timed(ctx, event,
861 timeval_sum(&now, &event->interval),
862 smbd_idle_event_handler, event);
864 /* We can't do much but fail here. */
865 SMB_ASSERT(event->te != NULL);
868 struct idle_event *event_add_idle(struct event_context *event_ctx,
869 TALLOC_CTX *mem_ctx,
870 struct timeval interval,
871 const char *name,
872 bool (*handler)(const struct timeval *now,
873 void *private_data),
874 void *private_data)
876 struct idle_event *result;
877 struct timeval now = timeval_current();
879 result = TALLOC_P(mem_ctx, struct idle_event);
880 if (result == NULL) {
881 DEBUG(0, ("talloc failed\n"));
882 return NULL;
885 result->interval = interval;
886 result->handler = handler;
887 result->private_data = private_data;
889 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
890 DEBUG(0, ("talloc failed\n"));
891 TALLOC_FREE(result);
892 return NULL;
895 result->te = event_add_timed(event_ctx, result,
896 timeval_sum(&now, &interval),
897 smbd_idle_event_handler, result);
898 if (result->te == NULL) {
899 DEBUG(0, ("event_add_timed failed\n"));
900 TALLOC_FREE(result);
901 return NULL;
904 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
905 return result;
908 static void smbd_sig_term_handler(struct tevent_context *ev,
909 struct tevent_signal *se,
910 int signum,
911 int count,
912 void *siginfo,
913 void *private_data)
915 exit_server_cleanly("termination signal");
918 void smbd_setup_sig_term_handler(void)
920 struct tevent_signal *se;
922 se = tevent_add_signal(smbd_event_context(),
923 smbd_event_context(),
924 SIGTERM, 0,
925 smbd_sig_term_handler,
926 NULL);
927 if (!se) {
928 exit_server("failed to setup SIGTERM handler");
932 static void smbd_sig_hup_handler(struct tevent_context *ev,
933 struct tevent_signal *se,
934 int signum,
935 int count,
936 void *siginfo,
937 void *private_data)
939 struct messaging_context *msg_ctx = talloc_get_type_abort(
940 private_data, struct messaging_context);
941 change_to_root_user();
942 DEBUG(1,("Reloading services after SIGHUP\n"));
943 reload_services(msg_ctx, smbd_server_conn->sock, False);
946 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
947 struct messaging_context *msg_ctx)
949 struct tevent_signal *se;
951 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
952 msg_ctx);
953 if (!se) {
954 exit_server("failed to setup SIGHUP handler");
958 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
960 fd_set r_fds, w_fds;
961 int selrtn = 0;
962 struct timeval to;
963 int maxfd = 0;
965 to.tv_sec = SMBD_SELECT_TIMEOUT;
966 to.tv_usec = 0;
969 * Setup the select fd sets.
972 FD_ZERO(&r_fds);
973 FD_ZERO(&w_fds);
976 * Are there any timed events waiting ? If so, ensure we don't
977 * select for longer than it would take to wait for them.
981 struct timeval now;
982 GetTimeOfDay(&now);
984 event_add_to_select_args(smbd_event_context(), &now,
985 &r_fds, &w_fds, &to, &maxfd);
988 /* Process a signal and timed events now... */
989 if (run_events(smbd_event_context(), &selrtn, NULL, NULL)) {
990 return NT_STATUS_RETRY;
994 int sav;
995 START_PROFILE(smbd_idle);
997 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
998 sav = errno;
1000 END_PROFILE(smbd_idle);
1001 errno = sav;
1004 /* Check if error */
1005 if (selrtn == -1) {
1006 if (errno == EINTR)
1007 return NT_STATUS_RETRY;
1008 else
1009 /* Maybe the socket is dead? */
1010 return map_nt_error_from_unix(errno);
1013 /* Process events until all available fds have been handled.
1014 * This allows for fair round-robin handling of all available fds
1015 * on each select() wakeup, while still maintaining responsiveness
1016 * by re-checking for signal and timed events between the handling
1017 * of each ready fd. */
1018 do {
1019 run_events(smbd_event_context(), &selrtn, &r_fds, &w_fds);
1020 } while (selrtn > 0);
1022 /* Processed all fds or timed out */
1023 if (selrtn == 0) {
1024 return NT_STATUS_RETRY;
1027 /* should not be reached */
1028 return NT_STATUS_INTERNAL_ERROR;
1032 * Only allow 5 outstanding trans requests. We're allocating memory, so
1033 * prevent a DoS.
1036 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1038 int count = 0;
1039 for (; list != NULL; list = list->next) {
1041 if (list->mid == mid) {
1042 return NT_STATUS_INVALID_PARAMETER;
1045 count += 1;
1047 if (count > 5) {
1048 return NT_STATUS_INSUFFICIENT_RESOURCES;
1051 return NT_STATUS_OK;
1055 These flags determine some of the permissions required to do an operation
1057 Note that I don't set NEED_WRITE on some write operations because they
1058 are used by some brain-dead clients when printing, and I don't want to
1059 force write permissions on print services.
1061 #define AS_USER (1<<0)
1062 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1063 #define TIME_INIT (1<<2)
1064 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1065 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1066 #define DO_CHDIR (1<<6)
1069 define a list of possible SMB messages and their corresponding
1070 functions. Any message that has a NULL function is unimplemented -
1071 please feel free to contribute implementations!
1073 static const struct smb_message_struct {
1074 const char *name;
1075 void (*fn)(struct smb_request *req);
1076 int flags;
1077 } smb_messages[256] = {
1079 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1080 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1081 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1082 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1083 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1084 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1085 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1086 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1087 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1088 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1089 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1090 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1091 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1092 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1093 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1094 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1095 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1096 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1097 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1098 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1099 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1100 /* 0x15 */ { NULL, NULL, 0 },
1101 /* 0x16 */ { NULL, NULL, 0 },
1102 /* 0x17 */ { NULL, NULL, 0 },
1103 /* 0x18 */ { NULL, NULL, 0 },
1104 /* 0x19 */ { NULL, NULL, 0 },
1105 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1106 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1107 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1108 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1109 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1110 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1111 /* 0x20 */ { "SMBwritec", NULL,0},
1112 /* 0x21 */ { NULL, NULL, 0 },
1113 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1114 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1115 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1116 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1117 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1118 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1119 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1120 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1121 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1122 /* 0x2b */ { "SMBecho",reply_echo,0},
1123 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1124 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1125 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1126 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1127 /* 0x30 */ { NULL, NULL, 0 },
1128 /* 0x31 */ { NULL, NULL, 0 },
1129 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1130 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1131 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1132 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1133 /* 0x36 */ { NULL, NULL, 0 },
1134 /* 0x37 */ { NULL, NULL, 0 },
1135 /* 0x38 */ { NULL, NULL, 0 },
1136 /* 0x39 */ { NULL, NULL, 0 },
1137 /* 0x3a */ { NULL, NULL, 0 },
1138 /* 0x3b */ { NULL, NULL, 0 },
1139 /* 0x3c */ { NULL, NULL, 0 },
1140 /* 0x3d */ { NULL, NULL, 0 },
1141 /* 0x3e */ { NULL, NULL, 0 },
1142 /* 0x3f */ { NULL, NULL, 0 },
1143 /* 0x40 */ { NULL, NULL, 0 },
1144 /* 0x41 */ { NULL, NULL, 0 },
1145 /* 0x42 */ { NULL, NULL, 0 },
1146 /* 0x43 */ { NULL, NULL, 0 },
1147 /* 0x44 */ { NULL, NULL, 0 },
1148 /* 0x45 */ { NULL, NULL, 0 },
1149 /* 0x46 */ { NULL, NULL, 0 },
1150 /* 0x47 */ { NULL, NULL, 0 },
1151 /* 0x48 */ { NULL, NULL, 0 },
1152 /* 0x49 */ { NULL, NULL, 0 },
1153 /* 0x4a */ { NULL, NULL, 0 },
1154 /* 0x4b */ { NULL, NULL, 0 },
1155 /* 0x4c */ { NULL, NULL, 0 },
1156 /* 0x4d */ { NULL, NULL, 0 },
1157 /* 0x4e */ { NULL, NULL, 0 },
1158 /* 0x4f */ { NULL, NULL, 0 },
1159 /* 0x50 */ { NULL, NULL, 0 },
1160 /* 0x51 */ { NULL, NULL, 0 },
1161 /* 0x52 */ { NULL, NULL, 0 },
1162 /* 0x53 */ { NULL, NULL, 0 },
1163 /* 0x54 */ { NULL, NULL, 0 },
1164 /* 0x55 */ { NULL, NULL, 0 },
1165 /* 0x56 */ { NULL, NULL, 0 },
1166 /* 0x57 */ { NULL, NULL, 0 },
1167 /* 0x58 */ { NULL, NULL, 0 },
1168 /* 0x59 */ { NULL, NULL, 0 },
1169 /* 0x5a */ { NULL, NULL, 0 },
1170 /* 0x5b */ { NULL, NULL, 0 },
1171 /* 0x5c */ { NULL, NULL, 0 },
1172 /* 0x5d */ { NULL, NULL, 0 },
1173 /* 0x5e */ { NULL, NULL, 0 },
1174 /* 0x5f */ { NULL, NULL, 0 },
1175 /* 0x60 */ { NULL, NULL, 0 },
1176 /* 0x61 */ { NULL, NULL, 0 },
1177 /* 0x62 */ { NULL, NULL, 0 },
1178 /* 0x63 */ { NULL, NULL, 0 },
1179 /* 0x64 */ { NULL, NULL, 0 },
1180 /* 0x65 */ { NULL, NULL, 0 },
1181 /* 0x66 */ { NULL, NULL, 0 },
1182 /* 0x67 */ { NULL, NULL, 0 },
1183 /* 0x68 */ { NULL, NULL, 0 },
1184 /* 0x69 */ { NULL, NULL, 0 },
1185 /* 0x6a */ { NULL, NULL, 0 },
1186 /* 0x6b */ { NULL, NULL, 0 },
1187 /* 0x6c */ { NULL, NULL, 0 },
1188 /* 0x6d */ { NULL, NULL, 0 },
1189 /* 0x6e */ { NULL, NULL, 0 },
1190 /* 0x6f */ { NULL, NULL, 0 },
1191 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1192 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1193 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1194 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1195 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1196 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1197 /* 0x76 */ { NULL, NULL, 0 },
1198 /* 0x77 */ { NULL, NULL, 0 },
1199 /* 0x78 */ { NULL, NULL, 0 },
1200 /* 0x79 */ { NULL, NULL, 0 },
1201 /* 0x7a */ { NULL, NULL, 0 },
1202 /* 0x7b */ { NULL, NULL, 0 },
1203 /* 0x7c */ { NULL, NULL, 0 },
1204 /* 0x7d */ { NULL, NULL, 0 },
1205 /* 0x7e */ { NULL, NULL, 0 },
1206 /* 0x7f */ { NULL, NULL, 0 },
1207 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1208 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1209 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1210 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1211 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1212 /* 0x85 */ { NULL, NULL, 0 },
1213 /* 0x86 */ { NULL, NULL, 0 },
1214 /* 0x87 */ { NULL, NULL, 0 },
1215 /* 0x88 */ { NULL, NULL, 0 },
1216 /* 0x89 */ { NULL, NULL, 0 },
1217 /* 0x8a */ { NULL, NULL, 0 },
1218 /* 0x8b */ { NULL, NULL, 0 },
1219 /* 0x8c */ { NULL, NULL, 0 },
1220 /* 0x8d */ { NULL, NULL, 0 },
1221 /* 0x8e */ { NULL, NULL, 0 },
1222 /* 0x8f */ { NULL, NULL, 0 },
1223 /* 0x90 */ { NULL, NULL, 0 },
1224 /* 0x91 */ { NULL, NULL, 0 },
1225 /* 0x92 */ { NULL, NULL, 0 },
1226 /* 0x93 */ { NULL, NULL, 0 },
1227 /* 0x94 */ { NULL, NULL, 0 },
1228 /* 0x95 */ { NULL, NULL, 0 },
1229 /* 0x96 */ { NULL, NULL, 0 },
1230 /* 0x97 */ { NULL, NULL, 0 },
1231 /* 0x98 */ { NULL, NULL, 0 },
1232 /* 0x99 */ { NULL, NULL, 0 },
1233 /* 0x9a */ { NULL, NULL, 0 },
1234 /* 0x9b */ { NULL, NULL, 0 },
1235 /* 0x9c */ { NULL, NULL, 0 },
1236 /* 0x9d */ { NULL, NULL, 0 },
1237 /* 0x9e */ { NULL, NULL, 0 },
1238 /* 0x9f */ { NULL, NULL, 0 },
1239 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1240 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1241 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1242 /* 0xa3 */ { NULL, NULL, 0 },
1243 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1244 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1245 /* 0xa6 */ { NULL, NULL, 0 },
1246 /* 0xa7 */ { NULL, NULL, 0 },
1247 /* 0xa8 */ { NULL, NULL, 0 },
1248 /* 0xa9 */ { NULL, NULL, 0 },
1249 /* 0xaa */ { NULL, NULL, 0 },
1250 /* 0xab */ { NULL, NULL, 0 },
1251 /* 0xac */ { NULL, NULL, 0 },
1252 /* 0xad */ { NULL, NULL, 0 },
1253 /* 0xae */ { NULL, NULL, 0 },
1254 /* 0xaf */ { NULL, NULL, 0 },
1255 /* 0xb0 */ { NULL, NULL, 0 },
1256 /* 0xb1 */ { NULL, NULL, 0 },
1257 /* 0xb2 */ { NULL, NULL, 0 },
1258 /* 0xb3 */ { NULL, NULL, 0 },
1259 /* 0xb4 */ { NULL, NULL, 0 },
1260 /* 0xb5 */ { NULL, NULL, 0 },
1261 /* 0xb6 */ { NULL, NULL, 0 },
1262 /* 0xb7 */ { NULL, NULL, 0 },
1263 /* 0xb8 */ { NULL, NULL, 0 },
1264 /* 0xb9 */ { NULL, NULL, 0 },
1265 /* 0xba */ { NULL, NULL, 0 },
1266 /* 0xbb */ { NULL, NULL, 0 },
1267 /* 0xbc */ { NULL, NULL, 0 },
1268 /* 0xbd */ { NULL, NULL, 0 },
1269 /* 0xbe */ { NULL, NULL, 0 },
1270 /* 0xbf */ { NULL, NULL, 0 },
1271 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1272 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1273 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1274 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1275 /* 0xc4 */ { NULL, NULL, 0 },
1276 /* 0xc5 */ { NULL, NULL, 0 },
1277 /* 0xc6 */ { NULL, NULL, 0 },
1278 /* 0xc7 */ { NULL, NULL, 0 },
1279 /* 0xc8 */ { NULL, NULL, 0 },
1280 /* 0xc9 */ { NULL, NULL, 0 },
1281 /* 0xca */ { NULL, NULL, 0 },
1282 /* 0xcb */ { NULL, NULL, 0 },
1283 /* 0xcc */ { NULL, NULL, 0 },
1284 /* 0xcd */ { NULL, NULL, 0 },
1285 /* 0xce */ { NULL, NULL, 0 },
1286 /* 0xcf */ { NULL, NULL, 0 },
1287 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1288 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1289 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1290 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1291 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1292 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1293 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1294 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1295 /* 0xd8 */ { NULL, NULL, 0 },
1296 /* 0xd9 */ { NULL, NULL, 0 },
1297 /* 0xda */ { NULL, NULL, 0 },
1298 /* 0xdb */ { NULL, NULL, 0 },
1299 /* 0xdc */ { NULL, NULL, 0 },
1300 /* 0xdd */ { NULL, NULL, 0 },
1301 /* 0xde */ { NULL, NULL, 0 },
1302 /* 0xdf */ { NULL, NULL, 0 },
1303 /* 0xe0 */ { NULL, NULL, 0 },
1304 /* 0xe1 */ { NULL, NULL, 0 },
1305 /* 0xe2 */ { NULL, NULL, 0 },
1306 /* 0xe3 */ { NULL, NULL, 0 },
1307 /* 0xe4 */ { NULL, NULL, 0 },
1308 /* 0xe5 */ { NULL, NULL, 0 },
1309 /* 0xe6 */ { NULL, NULL, 0 },
1310 /* 0xe7 */ { NULL, NULL, 0 },
1311 /* 0xe8 */ { NULL, NULL, 0 },
1312 /* 0xe9 */ { NULL, NULL, 0 },
1313 /* 0xea */ { NULL, NULL, 0 },
1314 /* 0xeb */ { NULL, NULL, 0 },
1315 /* 0xec */ { NULL, NULL, 0 },
1316 /* 0xed */ { NULL, NULL, 0 },
1317 /* 0xee */ { NULL, NULL, 0 },
1318 /* 0xef */ { NULL, NULL, 0 },
1319 /* 0xf0 */ { NULL, NULL, 0 },
1320 /* 0xf1 */ { NULL, NULL, 0 },
1321 /* 0xf2 */ { NULL, NULL, 0 },
1322 /* 0xf3 */ { NULL, NULL, 0 },
1323 /* 0xf4 */ { NULL, NULL, 0 },
1324 /* 0xf5 */ { NULL, NULL, 0 },
1325 /* 0xf6 */ { NULL, NULL, 0 },
1326 /* 0xf7 */ { NULL, NULL, 0 },
1327 /* 0xf8 */ { NULL, NULL, 0 },
1328 /* 0xf9 */ { NULL, NULL, 0 },
1329 /* 0xfa */ { NULL, NULL, 0 },
1330 /* 0xfb */ { NULL, NULL, 0 },
1331 /* 0xfc */ { NULL, NULL, 0 },
1332 /* 0xfd */ { NULL, NULL, 0 },
1333 /* 0xfe */ { NULL, NULL, 0 },
1334 /* 0xff */ { NULL, NULL, 0 }
1338 /*******************************************************************
1339 allocate and initialize a reply packet
1340 ********************************************************************/
1342 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1343 const char *inbuf, char **outbuf, uint8_t num_words,
1344 uint32_t num_bytes)
1347 * Protect against integer wrap
1349 if ((num_bytes > 0xffffff)
1350 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1351 char *msg;
1352 if (asprintf(&msg, "num_bytes too large: %u",
1353 (unsigned)num_bytes) == -1) {
1354 msg = CONST_DISCARD(char *, "num_bytes too large");
1356 smb_panic(msg);
1359 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1360 smb_size + num_words*2 + num_bytes);
1361 if (*outbuf == NULL) {
1362 return false;
1365 construct_reply_common(req, inbuf, *outbuf);
1366 srv_set_message(*outbuf, num_words, num_bytes, false);
1368 * Zero out the word area, the caller has to take care of the bcc area
1369 * himself
1371 if (num_words != 0) {
1372 memset(*outbuf + smb_vwv0, 0, num_words*2);
1375 return true;
1378 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1380 char *outbuf;
1381 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1382 num_bytes)) {
1383 smb_panic("could not allocate output buffer\n");
1385 req->outbuf = (uint8_t *)outbuf;
1389 /*******************************************************************
1390 Dump a packet to a file.
1391 ********************************************************************/
1393 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1395 int fd, i;
1396 char *fname = NULL;
1397 if (DEBUGLEVEL < 50) {
1398 return;
1401 if (len < 4) len = smb_len(data)+4;
1402 for (i=1;i<100;i++) {
1403 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1404 type ? "req" : "resp") == -1) {
1405 return;
1407 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1408 if (fd != -1 || errno != EEXIST) break;
1410 if (fd != -1) {
1411 ssize_t ret = write(fd, data, len);
1412 if (ret != len)
1413 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1414 close(fd);
1415 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1417 SAFE_FREE(fname);
1420 /****************************************************************************
1421 Prepare everything for calling the actual request function, and potentially
1422 call the request function via the "new" interface.
1424 Return False if the "legacy" function needs to be called, everything is
1425 prepared.
1427 Return True if we're done.
1429 I know this API sucks, but it is the one with the least code change I could
1430 find.
1431 ****************************************************************************/
1433 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1435 int flags;
1436 uint16 session_tag;
1437 connection_struct *conn = NULL;
1438 struct smbd_server_connection *sconn = req->sconn;
1440 errno = 0;
1442 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1443 * so subtract 4 from it. */
1444 if (!valid_smb_header(req->inbuf)
1445 || (size < (smb_size - 4))) {
1446 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1447 smb_len(req->inbuf)));
1448 exit_server_cleanly("Non-SMB packet");
1451 if (smb_messages[type].fn == NULL) {
1452 DEBUG(0,("Unknown message type %d!\n",type));
1453 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1454 reply_unknown_new(req, type);
1455 return NULL;
1458 flags = smb_messages[type].flags;
1460 /* In share mode security we must ignore the vuid. */
1461 session_tag = (lp_security() == SEC_SHARE)
1462 ? UID_FIELD_INVALID : req->vuid;
1463 conn = req->conn;
1465 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1466 (int)sys_getpid(), (unsigned long)conn));
1468 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1470 /* Ensure this value is replaced in the incoming packet. */
1471 SSVAL(req->inbuf,smb_uid,session_tag);
1474 * Ensure the correct username is in current_user_info. This is a
1475 * really ugly bugfix for problems with multiple session_setup_and_X's
1476 * being done and allowing %U and %G substitutions to work correctly.
1477 * There is a reason this code is done here, don't move it unless you
1478 * know what you're doing... :-).
1479 * JRA.
1482 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1483 user_struct *vuser = NULL;
1485 sconn->smb1.sessions.last_session_tag = session_tag;
1486 if(session_tag != UID_FIELD_INVALID) {
1487 vuser = get_valid_user_struct(sconn, session_tag);
1488 if (vuser) {
1489 set_current_user_info(
1490 vuser->server_info->sanitized_username,
1491 vuser->server_info->unix_name,
1492 vuser->server_info->info3->base.domain.string);
1497 /* Does this call need to be run as the connected user? */
1498 if (flags & AS_USER) {
1500 /* Does this call need a valid tree connection? */
1501 if (!conn) {
1503 * Amazingly, the error code depends on the command
1504 * (from Samba4).
1506 if (type == SMBntcreateX) {
1507 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1508 } else {
1509 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1511 return NULL;
1514 if (!change_to_user(conn,session_tag)) {
1515 DEBUG(0, ("Error: Could not change to user. Removing "
1516 "deferred open, mid=%llu.\n",
1517 (unsigned long long)req->mid));
1518 reply_force_doserror(req, ERRSRV, ERRbaduid);
1519 return conn;
1522 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1524 /* Does it need write permission? */
1525 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1526 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1527 return conn;
1530 /* IPC services are limited */
1531 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1532 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1533 return conn;
1535 } else {
1536 /* This call needs to be run as root */
1537 change_to_root_user();
1540 /* load service specific parameters */
1541 if (conn) {
1542 if (req->encrypted) {
1543 conn->encrypted_tid = true;
1544 /* encrypted required from now on. */
1545 conn->encrypt_level = Required;
1546 } else if (ENCRYPTION_REQUIRED(conn)) {
1547 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1548 exit_server_cleanly("encryption required "
1549 "on connection");
1550 return conn;
1554 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1555 (flags & (AS_USER|DO_CHDIR)
1556 ?True:False))) {
1557 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1558 return conn;
1560 conn->num_smb_operations++;
1563 /* does this protocol need to be run as guest? */
1564 if ((flags & AS_GUEST)
1565 && (!change_to_guest() ||
1566 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1567 sconn->client_id.name,
1568 sconn->client_id.addr))) {
1569 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1570 return conn;
1573 smb_messages[type].fn(req);
1574 return req->conn;
1577 /****************************************************************************
1578 Construct a reply to the incoming packet.
1579 ****************************************************************************/
1581 static void construct_reply(struct smbd_server_connection *sconn,
1582 char *inbuf, int size, size_t unread_bytes,
1583 uint32_t seqnum, bool encrypted,
1584 struct smb_perfcount_data *deferred_pcd)
1586 connection_struct *conn;
1587 struct smb_request *req;
1589 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1590 smb_panic("could not allocate smb_request");
1593 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1594 encrypted, seqnum)) {
1595 exit_server_cleanly("Invalid SMB request");
1598 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1600 /* we popped this message off the queue - keep original perf data */
1601 if (deferred_pcd)
1602 req->pcd = *deferred_pcd;
1603 else {
1604 SMB_PERFCOUNT_START(&req->pcd);
1605 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1606 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1609 conn = switch_message(req->cmd, req, size);
1611 if (req->unread_bytes) {
1612 /* writeX failed. drain socket. */
1613 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1614 req->unread_bytes) {
1615 smb_panic("failed to drain pending bytes");
1617 req->unread_bytes = 0;
1620 if (req->done) {
1621 TALLOC_FREE(req);
1622 return;
1625 if (req->outbuf == NULL) {
1626 return;
1629 if (CVAL(req->outbuf,0) == 0) {
1630 show_msg((char *)req->outbuf);
1633 if (!srv_send_smb(req->sconn,
1634 (char *)req->outbuf,
1635 true, req->seqnum+1,
1636 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1637 &req->pcd)) {
1638 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1641 TALLOC_FREE(req);
1643 return;
1646 /****************************************************************************
1647 Process an smb from the client
1648 ****************************************************************************/
1649 static void process_smb(struct smbd_server_connection *sconn,
1650 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1651 uint32_t seqnum, bool encrypted,
1652 struct smb_perfcount_data *deferred_pcd)
1654 int msg_type = CVAL(inbuf,0);
1656 DO_PROFILE_INC(smb_count);
1658 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1659 smb_len(inbuf) ) );
1660 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1661 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1663 if (msg_type != 0) {
1665 * NetBIOS session request, keepalive, etc.
1667 reply_special(sconn, (char *)inbuf, nread);
1668 goto done;
1671 if (sconn->using_smb2) {
1672 /* At this point we're not really using smb2,
1673 * we make the decision here.. */
1674 if (smbd_is_smb2_header(inbuf, nread)) {
1675 smbd_smb2_first_negprot(sconn, inbuf, nread);
1676 return;
1677 } else if (nread >= smb_size && valid_smb_header(inbuf)
1678 && CVAL(inbuf, smb_com) != 0x72) {
1679 /* This is a non-negprot SMB1 packet.
1680 Disable SMB2 from now on. */
1681 sconn->using_smb2 = false;
1685 show_msg((char *)inbuf);
1687 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1688 encrypted, deferred_pcd);
1689 sconn->trans_num++;
1691 done:
1692 sconn->smb1.num_requests++;
1694 /* The timeout_processing function isn't run nearly
1695 often enough to implement 'max log size' without
1696 overrunning the size of the file by many megabytes.
1697 This is especially true if we are running at debug
1698 level 10. Checking every 50 SMBs is a nice
1699 tradeoff of performance vs log file size overrun. */
1701 if ((sconn->smb1.num_requests % 50) == 0 &&
1702 need_to_check_log_size()) {
1703 change_to_root_user();
1704 check_log_size();
1708 /****************************************************************************
1709 Return a string containing the function name of a SMB command.
1710 ****************************************************************************/
1712 const char *smb_fn_name(int type)
1714 const char *unknown_name = "SMBunknown";
1716 if (smb_messages[type].name == NULL)
1717 return(unknown_name);
1719 return(smb_messages[type].name);
1722 /****************************************************************************
1723 Helper functions for contruct_reply.
1724 ****************************************************************************/
1726 void add_to_common_flags2(uint32 v)
1728 common_flags2 |= v;
1731 void remove_from_common_flags2(uint32 v)
1733 common_flags2 &= ~v;
1736 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1737 char *outbuf)
1739 srv_set_message(outbuf,0,0,false);
1741 SCVAL(outbuf, smb_com, req->cmd);
1742 SIVAL(outbuf,smb_rcls,0);
1743 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1744 SSVAL(outbuf,smb_flg2,
1745 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1746 common_flags2);
1747 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1749 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1750 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1751 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1752 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1755 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1757 construct_reply_common(req, (char *)req->inbuf, outbuf);
1761 * How many bytes have we already accumulated up to the current wct field
1762 * offset?
1765 size_t req_wct_ofs(struct smb_request *req)
1767 size_t buf_size;
1769 if (req->chain_outbuf == NULL) {
1770 return smb_wct - 4;
1772 buf_size = talloc_get_size(req->chain_outbuf);
1773 if ((buf_size % 4) != 0) {
1774 buf_size += (4 - (buf_size % 4));
1776 return buf_size - 4;
1780 * Hack around reply_nterror & friends not being aware of chained requests,
1781 * generating illegal (i.e. wct==0) chain replies.
1784 static void fixup_chain_error_packet(struct smb_request *req)
1786 uint8_t *outbuf = req->outbuf;
1787 req->outbuf = NULL;
1788 reply_outbuf(req, 2, 0);
1789 memcpy(req->outbuf, outbuf, smb_wct);
1790 TALLOC_FREE(outbuf);
1791 SCVAL(req->outbuf, smb_vwv0, 0xff);
1795 * @brief Find the smb_cmd offset of the last command pushed
1796 * @param[in] buf The buffer we're building up
1797 * @retval Where can we put our next andx cmd?
1799 * While chaining requests, the "next" request we're looking at needs to put
1800 * its SMB_Command before the data the previous request already built up added
1801 * to the chain. Find the offset to the place where we have to put our cmd.
1804 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1806 uint8_t cmd;
1807 size_t ofs;
1809 cmd = CVAL(buf, smb_com);
1811 SMB_ASSERT(is_andx_req(cmd));
1813 ofs = smb_vwv0;
1815 while (CVAL(buf, ofs) != 0xff) {
1817 if (!is_andx_req(CVAL(buf, ofs))) {
1818 return false;
1822 * ofs is from start of smb header, so add the 4 length
1823 * bytes. The next cmd is right after the wct field.
1825 ofs = SVAL(buf, ofs+2) + 4 + 1;
1827 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1830 *pofs = ofs;
1831 return true;
1835 * @brief Do the smb chaining at a buffer level
1836 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1837 * @param[in] smb_command The command that we want to issue
1838 * @param[in] wct How many words?
1839 * @param[in] vwv The words, already in network order
1840 * @param[in] bytes_alignment How shall we align "bytes"?
1841 * @param[in] num_bytes How many bytes?
1842 * @param[in] bytes The data the request ships
1844 * smb_splice_chain() adds the vwv and bytes to the request already present in
1845 * *poutbuf.
1848 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1849 uint8_t wct, const uint16_t *vwv,
1850 size_t bytes_alignment,
1851 uint32_t num_bytes, const uint8_t *bytes)
1853 uint8_t *outbuf;
1854 size_t old_size, new_size;
1855 size_t ofs;
1856 size_t chain_padding = 0;
1857 size_t bytes_padding = 0;
1858 bool first_request;
1860 old_size = talloc_get_size(*poutbuf);
1863 * old_size == smb_wct means we're pushing the first request in for
1864 * libsmb/
1867 first_request = (old_size == smb_wct);
1869 if (!first_request && ((old_size % 4) != 0)) {
1871 * Align the wct field of subsequent requests to a 4-byte
1872 * boundary
1874 chain_padding = 4 - (old_size % 4);
1878 * After the old request comes the new wct field (1 byte), the vwv's
1879 * and the num_bytes field. After at we might need to align the bytes
1880 * given to us to "bytes_alignment", increasing the num_bytes value.
1883 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1885 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1886 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1889 new_size += bytes_padding + num_bytes;
1891 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1892 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1893 (unsigned)new_size));
1894 return false;
1897 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1898 if (outbuf == NULL) {
1899 DEBUG(0, ("talloc failed\n"));
1900 return false;
1902 *poutbuf = outbuf;
1904 if (first_request) {
1905 SCVAL(outbuf, smb_com, smb_command);
1906 } else {
1907 size_t andx_cmd_ofs;
1909 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1910 DEBUG(1, ("invalid command chain\n"));
1911 *poutbuf = TALLOC_REALLOC_ARRAY(
1912 NULL, *poutbuf, uint8_t, old_size);
1913 return false;
1916 if (chain_padding != 0) {
1917 memset(outbuf + old_size, 0, chain_padding);
1918 old_size += chain_padding;
1921 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1922 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1925 ofs = old_size;
1928 * Push the chained request:
1930 * wct field
1933 SCVAL(outbuf, ofs, wct);
1934 ofs += 1;
1937 * vwv array
1940 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1941 ofs += sizeof(uint16_t) * wct;
1944 * bcc (byte count)
1947 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1948 ofs += sizeof(uint16_t);
1951 * padding
1954 if (bytes_padding != 0) {
1955 memset(outbuf + ofs, 0, bytes_padding);
1956 ofs += bytes_padding;
1960 * The bytes field
1963 memcpy(outbuf + ofs, bytes, num_bytes);
1965 return true;
1968 /****************************************************************************
1969 Construct a chained reply and add it to the already made reply
1970 ****************************************************************************/
1972 void chain_reply(struct smb_request *req)
1974 size_t smblen = smb_len(req->inbuf);
1975 size_t already_used, length_needed;
1976 uint8_t chain_cmd;
1977 uint32_t chain_offset; /* uint32_t to avoid overflow */
1979 uint8_t wct;
1980 uint16_t *vwv;
1981 uint16_t buflen;
1982 uint8_t *buf;
1984 if (IVAL(req->outbuf, smb_rcls) != 0) {
1985 fixup_chain_error_packet(req);
1989 * Any of the AndX requests and replies have at least a wct of
1990 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1991 * beginning of the SMB header to the next wct field.
1993 * None of the AndX requests put anything valuable in vwv[0] and [1],
1994 * so we can overwrite it here to form the chain.
1997 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1998 if (req->chain_outbuf == NULL) {
1999 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2000 req, req->outbuf, uint8_t,
2001 smb_len(req->outbuf) + 4);
2002 if (req->chain_outbuf == NULL) {
2003 smb_panic("talloc failed");
2006 req->outbuf = NULL;
2007 goto error;
2011 * Here we assume that this is the end of the chain. For that we need
2012 * to set "next command" to 0xff and the offset to 0. If we later find
2013 * more commands in the chain, this will be overwritten again.
2016 SCVAL(req->outbuf, smb_vwv0, 0xff);
2017 SCVAL(req->outbuf, smb_vwv0+1, 0);
2018 SSVAL(req->outbuf, smb_vwv1, 0);
2020 if (req->chain_outbuf == NULL) {
2022 * In req->chain_outbuf we collect all the replies. Start the
2023 * chain by copying in the first reply.
2025 * We do the realloc because later on we depend on
2026 * talloc_get_size to determine the length of
2027 * chain_outbuf. The reply_xxx routines might have
2028 * over-allocated (reply_pipe_read_and_X used to be such an
2029 * example).
2031 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2032 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2033 if (req->chain_outbuf == NULL) {
2034 smb_panic("talloc failed");
2036 req->outbuf = NULL;
2037 } else {
2039 * Update smb headers where subsequent chained commands
2040 * may have updated them.
2042 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2043 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2045 if (!smb_splice_chain(&req->chain_outbuf,
2046 CVAL(req->outbuf, smb_com),
2047 CVAL(req->outbuf, smb_wct),
2048 (uint16_t *)(req->outbuf + smb_vwv),
2049 0, smb_buflen(req->outbuf),
2050 (uint8_t *)smb_buf(req->outbuf))) {
2051 goto error;
2053 TALLOC_FREE(req->outbuf);
2057 * We use the old request's vwv field to grab the next chained command
2058 * and offset into the chained fields.
2061 chain_cmd = CVAL(req->vwv+0, 0);
2062 chain_offset = SVAL(req->vwv+1, 0);
2064 if (chain_cmd == 0xff) {
2066 * End of chain, no more requests from the client. So ship the
2067 * replies.
2069 smb_setlen((char *)(req->chain_outbuf),
2070 talloc_get_size(req->chain_outbuf) - 4);
2072 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2073 true, req->seqnum+1,
2074 IS_CONN_ENCRYPTED(req->conn)
2075 ||req->encrypted,
2076 &req->pcd)) {
2077 exit_server_cleanly("chain_reply: srv_send_smb "
2078 "failed.");
2080 TALLOC_FREE(req->chain_outbuf);
2081 req->done = true;
2082 return;
2085 /* add a new perfcounter for this element of chain */
2086 SMB_PERFCOUNT_ADD(&req->pcd);
2087 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2088 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2091 * Check if the client tries to fool us. The request so far uses the
2092 * space to the end of the byte buffer in the request just
2093 * processed. The chain_offset can't point into that area. If that was
2094 * the case, we could end up with an endless processing of the chain,
2095 * we would always handle the same request.
2098 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2099 if (chain_offset < already_used) {
2100 goto error;
2104 * Next check: Make sure the chain offset does not point beyond the
2105 * overall smb request length.
2108 length_needed = chain_offset+1; /* wct */
2109 if (length_needed > smblen) {
2110 goto error;
2114 * Now comes the pointer magic. Goal here is to set up req->vwv and
2115 * req->buf correctly again to be able to call the subsequent
2116 * switch_message(). The chain offset (the former vwv[1]) points at
2117 * the new wct field.
2120 wct = CVAL(smb_base(req->inbuf), chain_offset);
2123 * Next consistency check: Make the new vwv array fits in the overall
2124 * smb request.
2127 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2128 if (length_needed > smblen) {
2129 goto error;
2131 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2134 * Now grab the new byte buffer....
2137 buflen = SVAL(vwv+wct, 0);
2140 * .. and check that it fits.
2143 length_needed += buflen;
2144 if (length_needed > smblen) {
2145 goto error;
2147 buf = (uint8_t *)(vwv+wct+1);
2149 req->cmd = chain_cmd;
2150 req->wct = wct;
2151 req->vwv = vwv;
2152 req->buflen = buflen;
2153 req->buf = buf;
2155 switch_message(chain_cmd, req, smblen);
2157 if (req->outbuf == NULL) {
2159 * This happens if the chained command has suspended itself or
2160 * if it has called srv_send_smb() itself.
2162 return;
2166 * We end up here if the chained command was not itself chained or
2167 * suspended, but for example a close() command. We now need to splice
2168 * the chained commands' outbuf into the already built up chain_outbuf
2169 * and ship the result.
2171 goto done;
2173 error:
2175 * We end up here if there's any error in the chain syntax. Report a
2176 * DOS error, just like Windows does.
2178 reply_force_doserror(req, ERRSRV, ERRerror);
2179 fixup_chain_error_packet(req);
2181 done:
2183 * This scary statement intends to set the
2184 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2185 * to the value req->outbuf carries
2187 SSVAL(req->chain_outbuf, smb_flg2,
2188 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2189 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2192 * Transfer the error codes from the subrequest to the main one
2194 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2195 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2197 if (!smb_splice_chain(&req->chain_outbuf,
2198 CVAL(req->outbuf, smb_com),
2199 CVAL(req->outbuf, smb_wct),
2200 (uint16_t *)(req->outbuf + smb_vwv),
2201 0, smb_buflen(req->outbuf),
2202 (uint8_t *)smb_buf(req->outbuf))) {
2203 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2205 TALLOC_FREE(req->outbuf);
2207 smb_setlen((char *)(req->chain_outbuf),
2208 talloc_get_size(req->chain_outbuf) - 4);
2210 show_msg((char *)(req->chain_outbuf));
2212 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2213 true, req->seqnum+1,
2214 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2215 &req->pcd)) {
2216 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2218 TALLOC_FREE(req->chain_outbuf);
2219 req->done = true;
2222 /****************************************************************************
2223 Check if services need reloading.
2224 ****************************************************************************/
2226 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2228 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2230 if(last_smb_conf_reload_time == 0) {
2231 last_smb_conf_reload_time = t;
2232 /* Our printing subsystem might not be ready at smbd start up.
2233 Then no printer is available till the first printers check
2234 is performed. A lower initial interval circumvents this. */
2235 if ( printcap_cache_time > 60 )
2236 last_printer_reload_time = t - printcap_cache_time + 60;
2237 else
2238 last_printer_reload_time = t;
2241 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2242 /* randomize over 60 second the printcap reload to avoid all
2243 * process hitting cupsd at the same time */
2244 int time_range = 60;
2246 last_printer_reload_time += random() % time_range;
2247 mypid = getpid();
2250 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2251 reload_services(sconn->msg_ctx, sconn->sock, True);
2252 last_smb_conf_reload_time = t;
2255 /* 'printcap cache time = 0' disable the feature */
2257 if ( printcap_cache_time != 0 )
2259 /* see if it's time to reload or if the clock has been set back */
2261 if ( (t >= last_printer_reload_time+printcap_cache_time)
2262 || (t-last_printer_reload_time < 0) )
2264 DEBUG( 3,( "Printcap cache time expired.\n"));
2265 reload_printers(sconn->msg_ctx);
2266 last_printer_reload_time = t;
2271 static bool fd_is_readable(int fd)
2273 fd_set fds;
2274 struct timeval timeout = {0, };
2275 int ret;
2277 FD_ZERO(&fds);
2278 FD_SET(fd, &fds);
2280 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2281 if (ret == -1) {
2282 return false;
2284 return FD_ISSET(fd, &fds);
2287 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2289 /* TODO: make write nonblocking */
2292 static void smbd_server_connection_read_handler(
2293 struct smbd_server_connection *conn, int fd)
2295 uint8_t *inbuf = NULL;
2296 size_t inbuf_len = 0;
2297 size_t unread_bytes = 0;
2298 bool encrypted = false;
2299 TALLOC_CTX *mem_ctx = talloc_tos();
2300 NTSTATUS status;
2301 uint32_t seqnum;
2303 bool from_client = (conn->sock == fd);
2305 if (from_client) {
2306 smbd_lock_socket(conn);
2308 if (!fd_is_readable(fd)) {
2309 DEBUG(10,("the echo listener was faster\n"));
2310 smbd_unlock_socket(conn);
2311 return;
2314 /* TODO: make this completely nonblocking */
2315 status = receive_smb_talloc(mem_ctx, conn,
2316 (char **)(void *)&inbuf,
2317 0, /* timeout */
2318 &unread_bytes,
2319 &encrypted,
2320 &inbuf_len, &seqnum,
2321 false /* trusted channel */);
2322 smbd_unlock_socket(conn);
2323 } else {
2324 /* TODO: make this completely nonblocking */
2325 status = receive_smb_talloc(mem_ctx, conn,
2326 (char **)(void *)&inbuf,
2327 0, /* timeout */
2328 &unread_bytes,
2329 &encrypted,
2330 &inbuf_len, &seqnum,
2331 true /* trusted channel */);
2334 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2335 goto process;
2337 if (NT_STATUS_IS_ERR(status)) {
2338 exit_server_cleanly("failed to receive smb request");
2340 if (!NT_STATUS_IS_OK(status)) {
2341 return;
2344 process:
2345 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2346 seqnum, encrypted, NULL);
2349 static void smbd_server_connection_handler(struct event_context *ev,
2350 struct fd_event *fde,
2351 uint16_t flags,
2352 void *private_data)
2354 struct smbd_server_connection *conn = talloc_get_type(private_data,
2355 struct smbd_server_connection);
2357 if (flags & EVENT_FD_WRITE) {
2358 smbd_server_connection_write_handler(conn);
2359 return;
2361 if (flags & EVENT_FD_READ) {
2362 smbd_server_connection_read_handler(conn, conn->sock);
2363 return;
2367 static void smbd_server_echo_handler(struct event_context *ev,
2368 struct fd_event *fde,
2369 uint16_t flags,
2370 void *private_data)
2372 struct smbd_server_connection *conn = talloc_get_type(private_data,
2373 struct smbd_server_connection);
2375 if (flags & EVENT_FD_WRITE) {
2376 smbd_server_connection_write_handler(conn);
2377 return;
2379 if (flags & EVENT_FD_READ) {
2380 smbd_server_connection_read_handler(
2381 conn, conn->smb1.echo_handler.trusted_fd);
2382 return;
2386 /****************************************************************************
2387 received when we should release a specific IP
2388 ****************************************************************************/
2389 static void release_ip(const char *ip, void *priv)
2391 const char *addr = (const char *)priv;
2392 const char *p = addr;
2394 if (strncmp("::ffff:", addr, 7) == 0) {
2395 p = addr + 7;
2398 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2399 /* we can't afford to do a clean exit - that involves
2400 database writes, which would potentially mean we
2401 are still running after the failover has finished -
2402 we have to get rid of this process ID straight
2403 away */
2404 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2405 ip));
2406 /* note we must exit with non-zero status so the unclean handler gets
2407 called in the parent, so that the brl database is tickled */
2408 _exit(1);
2412 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2413 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2415 struct smbd_server_connection *sconn = talloc_get_type_abort(
2416 private_data, struct smbd_server_connection);
2418 release_ip((char *)data->data, sconn->client_id.addr);
2421 #ifdef CLUSTER_SUPPORT
2422 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2423 struct sockaddr_storage *client)
2425 socklen_t length;
2426 length = sizeof(*server);
2427 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2428 return -1;
2430 length = sizeof(*client);
2431 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2432 return -1;
2434 return 0;
2436 #endif
2439 * Send keepalive packets to our client
2441 static bool keepalive_fn(const struct timeval *now, void *private_data)
2443 struct smbd_server_connection *sconn = smbd_server_conn;
2444 bool ret;
2446 if (sconn->using_smb2) {
2447 /* Don't do keepalives on an SMB2 connection. */
2448 return false;
2451 smbd_lock_socket(smbd_server_conn);
2452 ret = send_keepalive(sconn->sock);
2453 smbd_unlock_socket(smbd_server_conn);
2455 if (!ret) {
2456 char addr[INET6_ADDRSTRLEN];
2458 * Try and give an error message saying what
2459 * client failed.
2461 DEBUG(0, ("send_keepalive failed for client %s. "
2462 "Error %s - exiting\n",
2463 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2464 strerror(errno)));
2465 return False;
2467 return True;
2471 * Do the recurring check if we're idle
2473 static bool deadtime_fn(const struct timeval *now, void *private_data)
2475 struct smbd_server_connection *sconn =
2476 (struct smbd_server_connection *)private_data;
2478 if ((conn_num_open(sconn) == 0)
2479 || (conn_idle_all(sconn, now->tv_sec))) {
2480 DEBUG( 2, ( "Closing idle connection\n" ) );
2481 messaging_send(sconn->msg_ctx,
2482 messaging_server_id(sconn->msg_ctx),
2483 MSG_SHUTDOWN, &data_blob_null);
2484 return False;
2487 return True;
2491 * Do the recurring log file and smb.conf reload checks.
2494 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2496 struct smbd_server_connection *sconn = talloc_get_type_abort(
2497 private_data, struct smbd_server_connection);
2498 change_to_root_user();
2500 /* update printer queue caches if necessary */
2501 update_monitored_printq_cache(sconn->msg_ctx);
2503 /* check if we need to reload services */
2504 check_reload(sconn, time(NULL));
2506 /* Change machine password if neccessary. */
2507 attempt_machine_password_change();
2510 * Force a log file check.
2512 force_check_log_size();
2513 check_log_size();
2514 return true;
2517 static int create_unlink_tmp(const char *dir)
2519 char *fname;
2520 int fd;
2522 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2523 if (fname == NULL) {
2524 errno = ENOMEM;
2525 return -1;
2527 fd = mkstemp(fname);
2528 if (fd == -1) {
2529 TALLOC_FREE(fname);
2530 return -1;
2532 if (unlink(fname) == -1) {
2533 int sys_errno = errno;
2534 close(fd);
2535 TALLOC_FREE(fname);
2536 errno = sys_errno;
2537 return -1;
2539 TALLOC_FREE(fname);
2540 return fd;
2543 struct smbd_echo_state {
2544 struct tevent_context *ev;
2545 struct iovec *pending;
2546 struct smbd_server_connection *sconn;
2547 int parent_pipe;
2549 struct tevent_fd *parent_fde;
2551 struct tevent_fd *read_fde;
2552 struct tevent_req *write_req;
2555 static void smbd_echo_writer_done(struct tevent_req *req);
2557 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2559 int num_pending;
2561 if (state->write_req != NULL) {
2562 return;
2565 num_pending = talloc_array_length(state->pending);
2566 if (num_pending == 0) {
2567 return;
2570 state->write_req = writev_send(state, state->ev, NULL,
2571 state->parent_pipe, false,
2572 state->pending, num_pending);
2573 if (state->write_req == NULL) {
2574 DEBUG(1, ("writev_send failed\n"));
2575 exit(1);
2578 talloc_steal(state->write_req, state->pending);
2579 state->pending = NULL;
2581 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2582 state);
2585 static void smbd_echo_writer_done(struct tevent_req *req)
2587 struct smbd_echo_state *state = tevent_req_callback_data(
2588 req, struct smbd_echo_state);
2589 ssize_t written;
2590 int err;
2592 written = writev_recv(req, &err);
2593 TALLOC_FREE(req);
2594 state->write_req = NULL;
2595 if (written == -1) {
2596 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2597 exit(1);
2599 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2600 smbd_echo_activate_writer(state);
2603 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2604 uint32_t seqnum)
2606 struct smb_request req;
2607 uint16_t num_replies;
2608 size_t out_len;
2609 char *outbuf;
2610 bool ok;
2612 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2613 DEBUG(10, ("Got netbios keepalive\n"));
2615 * Just swallow it
2617 return true;
2620 if (inbuf_len < smb_size) {
2621 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2622 return false;
2624 if (!valid_smb_header(inbuf)) {
2625 DEBUG(10, ("Got invalid SMB header\n"));
2626 return false;
2629 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2630 seqnum)) {
2631 return false;
2633 req.inbuf = inbuf;
2635 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2636 smb_messages[req.cmd].name
2637 ? smb_messages[req.cmd].name : "unknown"));
2639 if (req.cmd != SMBecho) {
2640 return false;
2642 if (req.wct < 1) {
2643 return false;
2646 num_replies = SVAL(req.vwv+0, 0);
2647 if (num_replies != 1) {
2648 /* Not a Windows "Hey, you're still there?" request */
2649 return false;
2652 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2653 1, req.buflen)) {
2654 DEBUG(10, ("create_outbuf failed\n"));
2655 return false;
2657 req.outbuf = (uint8_t *)outbuf;
2659 SSVAL(req.outbuf, smb_vwv0, num_replies);
2661 if (req.buflen > 0) {
2662 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2665 out_len = smb_len(req.outbuf) + 4;
2667 ok = srv_send_smb(req.sconn,
2668 (char *)outbuf,
2669 true, seqnum+1,
2670 false, &req.pcd);
2671 TALLOC_FREE(outbuf);
2672 if (!ok) {
2673 exit(1);
2676 return true;
2679 static void smbd_echo_exit(struct tevent_context *ev,
2680 struct tevent_fd *fde, uint16_t flags,
2681 void *private_data)
2683 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2684 exit(0);
2687 static void smbd_echo_reader(struct tevent_context *ev,
2688 struct tevent_fd *fde, uint16_t flags,
2689 void *private_data)
2691 struct smbd_echo_state *state = talloc_get_type_abort(
2692 private_data, struct smbd_echo_state);
2693 struct smbd_server_connection *sconn = state->sconn;
2694 size_t unread, num_pending;
2695 NTSTATUS status;
2696 struct iovec *tmp;
2697 size_t iov_len;
2698 uint32_t seqnum = 0;
2699 bool reply;
2700 bool ok;
2701 bool encrypted = false;
2703 smb_msleep(1000);
2705 ok = smbd_lock_socket_internal(sconn);
2706 if (!ok) {
2707 DEBUG(0, ("%s: failed to lock socket\n",
2708 __location__));
2709 exit(1);
2712 if (!fd_is_readable(sconn->sock)) {
2713 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2714 (int)sys_getpid()));
2715 ok = smbd_unlock_socket_internal(sconn);
2716 if (!ok) {
2717 DEBUG(1, ("%s: failed to unlock socket in\n",
2718 __location__));
2719 exit(1);
2721 return;
2724 num_pending = talloc_array_length(state->pending);
2725 tmp = talloc_realloc(state, state->pending, struct iovec,
2726 num_pending+1);
2727 if (tmp == NULL) {
2728 DEBUG(1, ("talloc_realloc failed\n"));
2729 exit(1);
2731 state->pending = tmp;
2733 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2735 status = receive_smb_talloc(state->pending, sconn,
2736 (char **)(void *)&state->pending[num_pending].iov_base,
2737 0 /* timeout */,
2738 &unread,
2739 &encrypted,
2740 &iov_len,
2741 &seqnum,
2742 false /* trusted_channel*/);
2743 if (!NT_STATUS_IS_OK(status)) {
2744 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2745 (int)sys_getpid(), nt_errstr(status)));
2746 exit(1);
2748 state->pending[num_pending].iov_len = iov_len;
2750 ok = smbd_unlock_socket_internal(sconn);
2751 if (!ok) {
2752 DEBUG(1, ("%s: failed to unlock socket in\n",
2753 __location__));
2754 exit(1);
2757 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2758 state->pending[num_pending].iov_len,
2759 seqnum);
2760 if (reply) {
2761 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2762 /* no check, shrinking by some bytes does not fail */
2763 state->pending = talloc_realloc(state, state->pending,
2764 struct iovec,
2765 num_pending);
2766 return;
2769 if (state->pending[num_pending].iov_len >= smb_size) {
2771 * place the seqnum in the packet so that the main process
2772 * can reply with signing
2774 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2775 smb_ss_field, seqnum);
2776 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2777 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2780 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2781 smbd_echo_activate_writer(state);
2784 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2785 int parent_pipe)
2787 struct smbd_echo_state *state;
2789 state = talloc_zero(sconn, struct smbd_echo_state);
2790 if (state == NULL) {
2791 DEBUG(1, ("talloc failed\n"));
2792 return;
2794 state->sconn = sconn;
2795 state->parent_pipe = parent_pipe;
2796 state->ev = s3_tevent_context_init(state);
2797 if (state->ev == NULL) {
2798 DEBUG(1, ("tevent_context_init failed\n"));
2799 TALLOC_FREE(state);
2800 return;
2802 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2803 TEVENT_FD_READ, smbd_echo_exit,
2804 state);
2805 if (state->parent_fde == NULL) {
2806 DEBUG(1, ("tevent_add_fd failed\n"));
2807 TALLOC_FREE(state);
2808 return;
2810 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2811 TEVENT_FD_READ, smbd_echo_reader,
2812 state);
2813 if (state->read_fde == NULL) {
2814 DEBUG(1, ("tevent_add_fd failed\n"));
2815 TALLOC_FREE(state);
2816 return;
2819 while (true) {
2820 if (tevent_loop_once(state->ev) == -1) {
2821 DEBUG(1, ("tevent_loop_once failed: %s\n",
2822 strerror(errno)));
2823 break;
2826 TALLOC_FREE(state);
2830 * Handle SMBecho requests in a forked child process
2832 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2834 int listener_pipe[2];
2835 int res;
2836 pid_t child;
2838 res = pipe(listener_pipe);
2839 if (res == -1) {
2840 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2841 return false;
2843 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2844 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2845 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2846 goto fail;
2849 child = sys_fork();
2850 if (child == 0) {
2851 NTSTATUS status;
2853 close(listener_pipe[0]);
2854 set_blocking(listener_pipe[1], false);
2856 status = reinit_after_fork(sconn->msg_ctx,
2857 smbd_event_context(),
2858 procid_self(), false);
2859 if (!NT_STATUS_IS_OK(status)) {
2860 DEBUG(1, ("reinit_after_fork failed: %s\n",
2861 nt_errstr(status)));
2862 exit(1);
2864 smbd_echo_loop(sconn, listener_pipe[1]);
2865 exit(0);
2867 close(listener_pipe[1]);
2868 listener_pipe[1] = -1;
2869 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2871 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2874 * Without smb signing this is the same as the normal smbd
2875 * listener. This needs to change once signing comes in.
2877 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2878 sconn,
2879 sconn->smb1.echo_handler.trusted_fd,
2880 EVENT_FD_READ,
2881 smbd_server_echo_handler,
2882 sconn);
2883 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2884 DEBUG(1, ("event_add_fd failed\n"));
2885 goto fail;
2888 return true;
2890 fail:
2891 if (listener_pipe[0] != -1) {
2892 close(listener_pipe[0]);
2894 if (listener_pipe[1] != -1) {
2895 close(listener_pipe[1]);
2897 sconn->smb1.echo_handler.trusted_fd = -1;
2898 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2899 close(sconn->smb1.echo_handler.socket_lock_fd);
2901 sconn->smb1.echo_handler.trusted_fd = -1;
2902 sconn->smb1.echo_handler.socket_lock_fd = -1;
2903 return false;
2906 #if CLUSTER_SUPPORT
2908 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2909 struct sockaddr_storage *srv,
2910 struct sockaddr_storage *clnt)
2912 struct ctdbd_connection *cconn;
2913 char tmp_addr[INET6_ADDRSTRLEN];
2914 char *addr;
2916 cconn = messaging_ctdbd_connection();
2917 if (cconn == NULL) {
2918 return NT_STATUS_NO_MEMORY;
2921 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2922 addr = talloc_strdup(cconn, tmp_addr);
2923 if (addr == NULL) {
2924 return NT_STATUS_NO_MEMORY;
2926 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2929 #endif
2931 /****************************************************************************
2932 Process commands from the client
2933 ****************************************************************************/
2935 void smbd_process(struct smbd_server_connection *sconn)
2937 TALLOC_CTX *frame = talloc_stackframe();
2938 struct sockaddr_storage ss;
2939 struct sockaddr *sa = NULL;
2940 socklen_t sa_socklen;
2941 struct tsocket_address *local_address = NULL;
2942 struct tsocket_address *remote_address = NULL;
2943 const char *remaddr = NULL;
2944 int ret;
2946 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2947 lp_security() != SEC_SHARE &&
2948 !lp_async_smb_echo_handler()) {
2950 * We're not making the desion here,
2951 * we're just allowing the client
2952 * to decide between SMB1 and SMB2
2953 * with the first negprot
2954 * packet.
2956 sconn->using_smb2 = true;
2959 /* Ensure child is set to blocking mode */
2960 set_blocking(sconn->sock,True);
2962 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2963 set_socket_options(sconn->sock, lp_socket_options());
2965 sa = (struct sockaddr *)(void *)&ss;
2966 sa_socklen = sizeof(ss);
2967 ret = getpeername(sconn->sock, sa, &sa_socklen);
2968 if (ret != 0) {
2969 int level = (errno == ENOTCONN)?2:0;
2970 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2971 exit_server_cleanly("getpeername() failed.\n");
2973 ret = tsocket_address_bsd_from_sockaddr(sconn,
2974 sa, sa_socklen,
2975 &remote_address);
2976 if (ret != 0) {
2977 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2978 __location__, strerror(errno)));
2979 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2982 sa = (struct sockaddr *)(void *)&ss;
2983 sa_socklen = sizeof(ss);
2984 ret = getsockname(sconn->sock, sa, &sa_socklen);
2985 if (ret != 0) {
2986 int level = (errno == ENOTCONN)?2:0;
2987 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2988 exit_server_cleanly("getsockname() failed.\n");
2990 ret = tsocket_address_bsd_from_sockaddr(sconn,
2991 sa, sa_socklen,
2992 &local_address);
2993 if (ret != 0) {
2994 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2995 __location__, strerror(errno)));
2996 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2999 sconn->local_address = local_address;
3000 sconn->remote_address = remote_address;
3002 if (tsocket_address_is_inet(remote_address, "ip")) {
3003 remaddr = tsocket_address_inet_addr_string(
3004 sconn->remote_address,
3005 talloc_tos());
3006 if (remaddr == NULL) {
3009 } else {
3010 remaddr = "0.0.0.0";
3013 /* this is needed so that we get decent entries
3014 in smbstatus for port 445 connects */
3015 set_remote_machine_name(remaddr, false);
3016 reload_services(sconn->msg_ctx, sconn->sock, true);
3019 * Before the first packet, check the global hosts allow/ hosts deny
3020 * parameters before doing any parsing of packets passed to us by the
3021 * client. This prevents attacks on our parsing code from hosts not in
3022 * the hosts allow list.
3025 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3026 sconn->client_id.name,
3027 sconn->client_id.addr)) {
3029 * send a negative session response "not listening on calling
3030 * name"
3032 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3033 DEBUG( 1, ("Connection denied from %s to %s\n",
3034 tsocket_address_string(remote_address, talloc_tos()),
3035 tsocket_address_string(local_address, talloc_tos())));
3036 (void)srv_send_smb(sconn,(char *)buf, false,
3037 0, false, NULL);
3038 exit_server_cleanly("connection denied");
3041 DEBUG(10, ("Connection allowed from %s to %s\n",
3042 tsocket_address_string(remote_address, talloc_tos()),
3043 tsocket_address_string(local_address, talloc_tos())));
3045 init_modules();
3047 smb_perfcount_init();
3049 if (!init_account_policy()) {
3050 exit_server("Could not open account policy tdb.\n");
3053 if (*lp_rootdir()) {
3054 if (chroot(lp_rootdir()) != 0) {
3055 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3056 exit_server("Failed to chroot()");
3058 if (chdir("/") == -1) {
3059 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3060 exit_server("Failed to chroot()");
3062 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3065 if (!srv_init_signing(sconn)) {
3066 exit_server("Failed to init smb_signing");
3069 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3070 exit_server("Failed to fork echo handler");
3073 /* Setup oplocks */
3074 if (!init_oplocks(sconn->msg_ctx))
3075 exit_server("Failed to init oplocks");
3077 /* register our message handlers */
3078 messaging_register(sconn->msg_ctx, NULL,
3079 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3080 messaging_register(sconn->msg_ctx, sconn,
3081 MSG_SMB_RELEASE_IP, msg_release_ip);
3082 messaging_register(sconn->msg_ctx, NULL,
3083 MSG_SMB_CLOSE_FILE, msg_close_file);
3086 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3087 * MSGs to all child processes
3089 messaging_deregister(sconn->msg_ctx,
3090 MSG_DEBUG, NULL);
3091 messaging_register(sconn->msg_ctx, NULL,
3092 MSG_DEBUG, debug_message);
3094 if ((lp_keepalive() != 0)
3095 && !(event_add_idle(smbd_event_context(), NULL,
3096 timeval_set(lp_keepalive(), 0),
3097 "keepalive", keepalive_fn,
3098 NULL))) {
3099 DEBUG(0, ("Could not add keepalive event\n"));
3100 exit(1);
3103 if (!(event_add_idle(smbd_event_context(), NULL,
3104 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3105 "deadtime", deadtime_fn, sconn))) {
3106 DEBUG(0, ("Could not add deadtime event\n"));
3107 exit(1);
3110 if (!(event_add_idle(smbd_event_context(), NULL,
3111 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3112 "housekeeping", housekeeping_fn, sconn))) {
3113 DEBUG(0, ("Could not add housekeeping event\n"));
3114 exit(1);
3117 #ifdef CLUSTER_SUPPORT
3119 if (lp_clustering()) {
3121 * We need to tell ctdb about our client's TCP
3122 * connection, so that for failover ctdbd can send
3123 * tickle acks, triggering a reconnection by the
3124 * client.
3127 struct sockaddr_storage srv, clnt;
3129 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3130 NTSTATUS status;
3131 status = smbd_register_ips(sconn, &srv, &clnt);
3132 if (!NT_STATUS_IS_OK(status)) {
3133 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3134 nt_errstr(status)));
3136 } else
3138 DEBUG(0,("Unable to get tcp info for "
3139 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3140 strerror(errno)));
3144 #endif
3146 sconn->nbt.got_session = false;
3148 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3150 sconn->smb1.sessions.done_sesssetup = false;
3151 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3152 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3153 /* users from session setup */
3154 sconn->smb1.sessions.session_userlist = NULL;
3155 /* workgroup from session setup. */
3156 sconn->smb1.sessions.session_workgroup = NULL;
3157 /* this holds info on user ids that are already validated for this VC */
3158 sconn->smb1.sessions.validated_users = NULL;
3159 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3160 sconn->smb1.sessions.num_validated_vuids = 0;
3162 conn_init(sconn);
3163 if (!init_dptrs(sconn)) {
3164 exit_server("init_dptrs() failed");
3167 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3168 sconn,
3169 sconn->sock,
3170 EVENT_FD_READ,
3171 smbd_server_connection_handler,
3172 sconn);
3173 if (!sconn->smb1.fde) {
3174 exit_server("failed to create smbd_server_connection fde");
3177 TALLOC_FREE(frame);
3179 while (True) {
3180 NTSTATUS status;
3182 frame = talloc_stackframe_pool(8192);
3184 errno = 0;
3186 status = smbd_server_connection_loop_once(sconn);
3187 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3188 !NT_STATUS_IS_OK(status)) {
3189 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3190 " exiting\n", nt_errstr(status)));
3191 break;
3194 TALLOC_FREE(frame);
3197 exit_server_cleanly(NULL);
3200 bool req_is_in_chain(struct smb_request *req)
3202 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3204 * We're right now handling a subsequent request, so we must
3205 * be in a chain
3207 return true;
3210 if (!is_andx_req(req->cmd)) {
3211 return false;
3214 if (req->wct < 2) {
3216 * Okay, an illegal request, but definitely not chained :-)
3218 return false;
3221 return (CVAL(req->vwv+0, 0) != 0xFF);