s3-printing: Initiate pcap reload from parent smbd
[Samba/gbeck.git] / source3 / smbd / process.c
blobe5b6f681995722bcbddc82c09ab16ffc8e05bf6f
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 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
59 return false;
62 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
64 return true;
67 void smbd_lock_socket(struct smbd_server_connection *sconn)
69 if (!smbd_lock_socket_internal(sconn)) {
70 exit_server_cleanly("failed to lock socket");
74 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
76 bool ok;
78 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
79 return true;
82 sconn->smb1.echo_handler.ref_count--;
84 if (sconn->smb1.echo_handler.ref_count > 0) {
85 return true;
88 do {
89 ok = fcntl_lock(
90 sconn->smb1.echo_handler.socket_lock_fd,
91 SMB_F_SETLKW, 0, 0, F_UNLCK);
92 } while (!ok && (errno == EINTR));
94 if (!ok) {
95 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
96 return false;
99 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
101 return true;
104 void smbd_unlock_socket(struct smbd_server_connection *sconn)
106 if (!smbd_unlock_socket_internal(sconn)) {
107 exit_server_cleanly("failed to unlock socket");
111 /* Accessor function for smb_read_error for smbd functions. */
113 /****************************************************************************
114 Send an smb to a fd.
115 ****************************************************************************/
117 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
118 bool do_signing, uint32_t seqnum,
119 bool do_encrypt,
120 struct smb_perfcount_data *pcd)
122 size_t len = 0;
123 size_t nwritten=0;
124 ssize_t ret;
125 char *buf_out = buffer;
127 smbd_lock_socket(sconn);
129 if (do_signing) {
130 /* Sign the outgoing packet if required. */
131 srv_calculate_sign_mac(sconn, buf_out, seqnum);
134 if (do_encrypt) {
135 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
136 if (!NT_STATUS_IS_OK(status)) {
137 DEBUG(0, ("send_smb: SMB encryption failed "
138 "on outgoing packet! Error %s\n",
139 nt_errstr(status) ));
140 goto out;
144 len = smb_len(buf_out) + 4;
146 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
147 if (ret <= 0) {
149 char addr[INET6_ADDRSTRLEN];
151 * Try and give an error message saying what
152 * client failed.
154 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
155 (int)sys_getpid(), (int)len,
156 get_peer_addr(sconn->sock, addr, sizeof(addr)),
157 (int)ret, strerror(errno) ));
159 srv_free_enc_buffer(buf_out);
160 goto out;
163 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
164 srv_free_enc_buffer(buf_out);
165 out:
166 SMB_PERFCOUNT_END(pcd);
168 smbd_unlock_socket(sconn);
169 return true;
172 /*******************************************************************
173 Setup the word count and byte count for a smb message.
174 ********************************************************************/
176 int srv_set_message(char *buf,
177 int num_words,
178 int num_bytes,
179 bool zero)
181 if (zero && (num_words || num_bytes)) {
182 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
184 SCVAL(buf,smb_wct,num_words);
185 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
186 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
187 return (smb_size + num_words*2 + num_bytes);
190 static bool valid_smb_header(const uint8_t *inbuf)
192 if (is_encrypted_packet(inbuf)) {
193 return true;
196 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
197 * but it just looks weird to call strncmp for this one.
199 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
202 /* Socket functions for smbd packet processing. */
204 static bool valid_packet_size(size_t len)
207 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
208 * of header. Don't print the error if this fits.... JRA.
211 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
212 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
213 (unsigned long)len));
214 return false;
216 return true;
219 static NTSTATUS read_packet_remainder(int fd, char *buffer,
220 unsigned int timeout, ssize_t len)
222 NTSTATUS status;
224 if (len <= 0) {
225 return NT_STATUS_OK;
228 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
229 if (!NT_STATUS_IS_OK(status)) {
230 char addr[INET6_ADDRSTRLEN];
231 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
232 "error = %s.\n",
233 get_peer_addr(fd, addr, sizeof(addr)),
234 nt_errstr(status)));
236 return status;
239 /****************************************************************************
240 Attempt a zerocopy writeX read. We know here that len > smb_size-4
241 ****************************************************************************/
244 * Unfortunately, earlier versions of smbclient/libsmbclient
245 * don't send this "standard" writeX header. I've fixed this
246 * for 3.2 but we'll use the old method with earlier versions.
247 * Windows and CIFSFS at least use this standard size. Not
248 * sure about MacOSX.
251 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
252 (2*14) + /* word count (including bcc) */ \
253 1 /* pad byte */)
255 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
256 const char lenbuf[4],
257 struct smbd_server_connection *sconn,
258 char **buffer,
259 unsigned int timeout,
260 size_t *p_unread,
261 size_t *len_ret)
263 /* Size of a WRITEX call (+4 byte len). */
264 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
265 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
266 ssize_t toread;
267 NTSTATUS status;
269 memcpy(writeX_header, lenbuf, 4);
271 status = read_fd_with_timeout(
272 sconn->sock, writeX_header + 4,
273 STANDARD_WRITE_AND_X_HEADER_SIZE,
274 STANDARD_WRITE_AND_X_HEADER_SIZE,
275 timeout, NULL);
277 if (!NT_STATUS_IS_OK(status)) {
278 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
279 "error = %s.\n", sconn->client_id.addr,
280 nt_errstr(status)));
281 return status;
285 * Ok - now try and see if this is a possible
286 * valid writeX call.
289 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
291 * If the data offset is beyond what
292 * we've read, drain the extra bytes.
294 uint16_t doff = SVAL(writeX_header,smb_vwv11);
295 ssize_t newlen;
297 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
298 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
299 if (drain_socket(sconn->sock, drain) != drain) {
300 smb_panic("receive_smb_raw_talloc_partial_read:"
301 " failed to drain pending bytes");
303 } else {
304 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
307 /* Spoof down the length and null out the bcc. */
308 set_message_bcc(writeX_header, 0);
309 newlen = smb_len(writeX_header);
311 /* Copy the header we've written. */
313 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
314 writeX_header,
315 sizeof(writeX_header));
317 if (*buffer == NULL) {
318 DEBUG(0, ("Could not allocate inbuf of length %d\n",
319 (int)sizeof(writeX_header)));
320 return NT_STATUS_NO_MEMORY;
323 /* Work out the remaining bytes. */
324 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
325 *len_ret = newlen + 4;
326 return NT_STATUS_OK;
329 if (!valid_packet_size(len)) {
330 return NT_STATUS_INVALID_PARAMETER;
334 * Not a valid writeX call. Just do the standard
335 * talloc and return.
338 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
340 if (*buffer == NULL) {
341 DEBUG(0, ("Could not allocate inbuf of length %d\n",
342 (int)len+4));
343 return NT_STATUS_NO_MEMORY;
346 /* Copy in what we already read. */
347 memcpy(*buffer,
348 writeX_header,
349 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
350 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
352 if(toread > 0) {
353 status = read_packet_remainder(
354 sconn->sock,
355 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
356 timeout, toread);
358 if (!NT_STATUS_IS_OK(status)) {
359 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
360 nt_errstr(status)));
361 return status;
365 *len_ret = len + 4;
366 return NT_STATUS_OK;
369 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
370 struct smbd_server_connection *sconn,
371 char **buffer, unsigned int timeout,
372 size_t *p_unread, size_t *plen)
374 char lenbuf[4];
375 size_t len;
376 int min_recv_size = lp_min_receive_file_size();
377 NTSTATUS status;
379 *p_unread = 0;
381 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
382 &len);
383 if (!NT_STATUS_IS_OK(status)) {
384 return status;
387 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
388 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
389 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
390 !srv_is_signing_active(sconn) &&
391 sconn->smb1.echo_handler.trusted_fde == NULL) {
393 return receive_smb_raw_talloc_partial_read(
394 mem_ctx, lenbuf, sconn, buffer, timeout,
395 p_unread, plen);
398 if (!valid_packet_size(len)) {
399 return NT_STATUS_INVALID_PARAMETER;
403 * The +4 here can't wrap, we've checked the length above already.
406 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
408 if (*buffer == NULL) {
409 DEBUG(0, ("Could not allocate inbuf of length %d\n",
410 (int)len+4));
411 return NT_STATUS_NO_MEMORY;
414 memcpy(*buffer, lenbuf, sizeof(lenbuf));
416 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
417 if (!NT_STATUS_IS_OK(status)) {
418 return status;
421 *plen = len + 4;
422 return NT_STATUS_OK;
425 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
426 struct smbd_server_connection *sconn,
427 char **buffer, unsigned int timeout,
428 size_t *p_unread, bool *p_encrypted,
429 size_t *p_len,
430 uint32_t *seqnum,
431 bool trusted_channel)
433 size_t len = 0;
434 NTSTATUS status;
436 *p_encrypted = false;
438 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
439 p_unread, &len);
440 if (!NT_STATUS_IS_OK(status)) {
441 DEBUG(1, ("read_smb_length_return_keepalive failed for "
442 "client %s read error = %s.\n",
443 sconn->client_id.addr, nt_errstr(status)));
444 return status;
447 if (is_encrypted_packet((uint8_t *)*buffer)) {
448 status = srv_decrypt_buffer(*buffer);
449 if (!NT_STATUS_IS_OK(status)) {
450 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
451 "incoming packet! Error %s\n",
452 nt_errstr(status) ));
453 return status;
455 *p_encrypted = true;
458 /* Check the incoming SMB signature. */
459 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
460 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
461 "incoming packet!\n"));
462 return NT_STATUS_INVALID_NETWORK_RESPONSE;
465 *p_len = len;
466 return NT_STATUS_OK;
470 * Initialize a struct smb_request from an inbuf
473 static bool init_smb_request(struct smb_request *req,
474 struct smbd_server_connection *sconn,
475 const uint8 *inbuf,
476 size_t unread_bytes, bool encrypted,
477 uint32_t seqnum)
479 size_t req_size = smb_len(inbuf) + 4;
480 /* Ensure we have at least smb_size bytes. */
481 if (req_size < smb_size) {
482 DEBUG(0,("init_smb_request: invalid request size %u\n",
483 (unsigned int)req_size ));
484 return false;
486 req->cmd = CVAL(inbuf, smb_com);
487 req->flags2 = SVAL(inbuf, smb_flg2);
488 req->smbpid = SVAL(inbuf, smb_pid);
489 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
490 req->seqnum = seqnum;
491 req->vuid = SVAL(inbuf, smb_uid);
492 req->tid = SVAL(inbuf, smb_tid);
493 req->wct = CVAL(inbuf, smb_wct);
494 req->vwv = (uint16_t *)(inbuf+smb_vwv);
495 req->buflen = smb_buflen(inbuf);
496 req->buf = (const uint8_t *)smb_buf(inbuf);
497 req->unread_bytes = unread_bytes;
498 req->encrypted = encrypted;
499 req->sconn = sconn;
500 req->conn = conn_find(sconn,req->tid);
501 req->chain_fsp = NULL;
502 req->chain_outbuf = NULL;
503 req->done = false;
504 req->smb2req = NULL;
505 smb_init_perfcount_data(&req->pcd);
507 /* Ensure we have at least wct words and 2 bytes of bcc. */
508 if (smb_size + req->wct*2 > req_size) {
509 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
510 (unsigned int)req->wct,
511 (unsigned int)req_size));
512 return false;
514 /* Ensure bcc is correct. */
515 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
516 DEBUG(0,("init_smb_request: invalid bcc number %u "
517 "(wct = %u, size %u)\n",
518 (unsigned int)req->buflen,
519 (unsigned int)req->wct,
520 (unsigned int)req_size));
521 return false;
524 req->outbuf = NULL;
525 return true;
528 static void process_smb(struct smbd_server_connection *conn,
529 uint8_t *inbuf, size_t nread, size_t unread_bytes,
530 uint32_t seqnum, bool encrypted,
531 struct smb_perfcount_data *deferred_pcd);
533 static void smbd_deferred_open_timer(struct event_context *ev,
534 struct timed_event *te,
535 struct timeval _tval,
536 void *private_data)
538 struct pending_message_list *msg = talloc_get_type(private_data,
539 struct pending_message_list);
540 TALLOC_CTX *mem_ctx = talloc_tos();
541 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
542 uint8_t *inbuf;
544 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
545 msg->buf.length);
546 if (inbuf == NULL) {
547 exit_server("smbd_deferred_open_timer: talloc failed\n");
548 return;
551 /* We leave this message on the queue so the open code can
552 know this is a retry. */
553 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
554 (unsigned long long)mid ));
556 /* Mark the message as processed so this is not
557 * re-processed in error. */
558 msg->processed = true;
560 process_smb(smbd_server_conn, inbuf,
561 msg->buf.length, 0,
562 msg->seqnum, msg->encrypted, &msg->pcd);
564 /* If it's still there and was processed, remove it. */
565 msg = get_deferred_open_message_smb(mid);
566 if (msg && msg->processed) {
567 remove_deferred_open_message_smb(mid);
571 /****************************************************************************
572 Function to push a message onto the tail of a linked list of smb messages ready
573 for processing.
574 ****************************************************************************/
576 static bool push_queued_message(struct smb_request *req,
577 struct timeval request_time,
578 struct timeval end_time,
579 char *private_data, size_t private_len)
581 int msg_len = smb_len(req->inbuf) + 4;
582 struct pending_message_list *msg;
584 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
586 if(msg == NULL) {
587 DEBUG(0,("push_message: malloc fail (1)\n"));
588 return False;
591 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
592 if(msg->buf.data == NULL) {
593 DEBUG(0,("push_message: malloc fail (2)\n"));
594 TALLOC_FREE(msg);
595 return False;
598 msg->request_time = request_time;
599 msg->seqnum = req->seqnum;
600 msg->encrypted = req->encrypted;
601 msg->processed = false;
602 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
604 if (private_data) {
605 msg->private_data = data_blob_talloc(msg, private_data,
606 private_len);
607 if (msg->private_data.data == NULL) {
608 DEBUG(0,("push_message: malloc fail (3)\n"));
609 TALLOC_FREE(msg);
610 return False;
614 msg->te = event_add_timed(smbd_event_context(),
615 msg,
616 end_time,
617 smbd_deferred_open_timer,
618 msg);
619 if (!msg->te) {
620 DEBUG(0,("push_message: event_add_timed failed\n"));
621 TALLOC_FREE(msg);
622 return false;
625 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
627 DEBUG(10,("push_message: pushed message length %u on "
628 "deferred_open_queue\n", (unsigned int)msg_len));
630 return True;
633 /****************************************************************************
634 Function to delete a sharing violation open message by mid.
635 ****************************************************************************/
637 void remove_deferred_open_message_smb(uint64_t mid)
639 struct pending_message_list *pml;
641 if (smbd_server_conn->using_smb2) {
642 remove_deferred_open_message_smb2(smbd_server_conn, mid);
643 return;
646 for (pml = deferred_open_queue; pml; pml = pml->next) {
647 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
648 DEBUG(10,("remove_deferred_open_message_smb: "
649 "deleting mid %llu len %u\n",
650 (unsigned long long)mid,
651 (unsigned int)pml->buf.length ));
652 DLIST_REMOVE(deferred_open_queue, pml);
653 TALLOC_FREE(pml);
654 return;
659 /****************************************************************************
660 Move a sharing violation open retry message to the front of the list and
661 schedule it for immediate processing.
662 ****************************************************************************/
664 void schedule_deferred_open_message_smb(uint64_t mid)
666 struct pending_message_list *pml;
667 int i = 0;
669 if (smbd_server_conn->using_smb2) {
670 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
671 return;
674 for (pml = deferred_open_queue; pml; pml = pml->next) {
675 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
677 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
678 "msg_mid = %llu\n",
679 i++,
680 (unsigned long long)msg_mid ));
682 if (mid == msg_mid) {
683 struct timed_event *te;
685 if (pml->processed) {
686 /* A processed message should not be
687 * rescheduled. */
688 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
689 "message mid %llu was already processed\n",
690 (unsigned long long)msg_mid ));
691 continue;
694 DEBUG(10,("schedule_deferred_open_message_smb: "
695 "scheduling mid %llu\n",
696 (unsigned long long)mid ));
698 te = event_add_timed(smbd_event_context(),
699 pml,
700 timeval_zero(),
701 smbd_deferred_open_timer,
702 pml);
703 if (!te) {
704 DEBUG(10,("schedule_deferred_open_message_smb: "
705 "event_add_timed() failed, "
706 "skipping mid %llu\n",
707 (unsigned long long)msg_mid ));
710 TALLOC_FREE(pml->te);
711 pml->te = te;
712 DLIST_PROMOTE(deferred_open_queue, pml);
713 return;
717 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
718 "find message mid %llu\n",
719 (unsigned long long)mid ));
722 /****************************************************************************
723 Return true if this mid is on the deferred queue and was not yet processed.
724 ****************************************************************************/
726 bool open_was_deferred(uint64_t mid)
728 struct pending_message_list *pml;
730 if (smbd_server_conn->using_smb2) {
731 return open_was_deferred_smb2(smbd_server_conn, mid);
734 for (pml = deferred_open_queue; pml; pml = pml->next) {
735 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
736 return True;
739 return False;
742 /****************************************************************************
743 Return the message queued by this mid.
744 ****************************************************************************/
746 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
748 struct pending_message_list *pml;
750 for (pml = deferred_open_queue; pml; pml = pml->next) {
751 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
752 return pml;
755 return NULL;
758 /****************************************************************************
759 Get the state data queued by this mid.
760 ****************************************************************************/
762 bool get_deferred_open_message_state(struct smb_request *smbreq,
763 struct timeval *p_request_time,
764 void **pp_state)
766 struct pending_message_list *pml;
768 if (smbd_server_conn->using_smb2) {
769 return get_deferred_open_message_state_smb2(smbreq->smb2req,
770 p_request_time,
771 pp_state);
774 pml = get_deferred_open_message_smb(smbreq->mid);
775 if (!pml) {
776 return false;
778 if (p_request_time) {
779 *p_request_time = pml->request_time;
781 if (pp_state) {
782 *pp_state = (void *)pml->private_data.data;
784 return true;
787 /****************************************************************************
788 Function to push a deferred open smb message onto a linked list of local smb
789 messages ready for processing.
790 ****************************************************************************/
792 bool push_deferred_open_message_smb(struct smb_request *req,
793 struct timeval request_time,
794 struct timeval timeout,
795 struct file_id id,
796 char *private_data, size_t priv_len)
798 struct timeval end_time;
800 if (req->smb2req) {
801 return push_deferred_open_message_smb2(req->smb2req,
802 request_time,
803 timeout,
805 private_data,
806 priv_len);
809 if (req->unread_bytes) {
810 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
811 "unread_bytes = %u\n",
812 (unsigned int)req->unread_bytes ));
813 smb_panic("push_deferred_open_message_smb: "
814 "logic error unread_bytes != 0" );
817 end_time = timeval_sum(&request_time, &timeout);
819 DEBUG(10,("push_deferred_open_message_smb: pushing message "
820 "len %u mid %llu timeout time [%u.%06u]\n",
821 (unsigned int) smb_len(req->inbuf)+4,
822 (unsigned long long)req->mid,
823 (unsigned int)end_time.tv_sec,
824 (unsigned int)end_time.tv_usec));
826 return push_queued_message(req, request_time, end_time,
827 private_data, priv_len);
830 struct idle_event {
831 struct timed_event *te;
832 struct timeval interval;
833 char *name;
834 bool (*handler)(const struct timeval *now, void *private_data);
835 void *private_data;
838 static void smbd_idle_event_handler(struct event_context *ctx,
839 struct timed_event *te,
840 struct timeval now,
841 void *private_data)
843 struct idle_event *event =
844 talloc_get_type_abort(private_data, struct idle_event);
846 TALLOC_FREE(event->te);
848 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
849 event->name, event->te));
851 if (!event->handler(&now, event->private_data)) {
852 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
853 event->name, event->te));
854 /* Don't repeat, delete ourselves */
855 TALLOC_FREE(event);
856 return;
859 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
860 event->name, event->te));
862 event->te = event_add_timed(ctx, event,
863 timeval_sum(&now, &event->interval),
864 smbd_idle_event_handler, event);
866 /* We can't do much but fail here. */
867 SMB_ASSERT(event->te != NULL);
870 struct idle_event *event_add_idle(struct event_context *event_ctx,
871 TALLOC_CTX *mem_ctx,
872 struct timeval interval,
873 const char *name,
874 bool (*handler)(const struct timeval *now,
875 void *private_data),
876 void *private_data)
878 struct idle_event *result;
879 struct timeval now = timeval_current();
881 result = TALLOC_P(mem_ctx, struct idle_event);
882 if (result == NULL) {
883 DEBUG(0, ("talloc failed\n"));
884 return NULL;
887 result->interval = interval;
888 result->handler = handler;
889 result->private_data = private_data;
891 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
892 DEBUG(0, ("talloc failed\n"));
893 TALLOC_FREE(result);
894 return NULL;
897 result->te = event_add_timed(event_ctx, result,
898 timeval_sum(&now, &interval),
899 smbd_idle_event_handler, result);
900 if (result->te == NULL) {
901 DEBUG(0, ("event_add_timed failed\n"));
902 TALLOC_FREE(result);
903 return NULL;
906 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
907 return result;
910 static void smbd_sig_term_handler(struct tevent_context *ev,
911 struct tevent_signal *se,
912 int signum,
913 int count,
914 void *siginfo,
915 void *private_data)
917 exit_server_cleanly("termination signal");
920 void smbd_setup_sig_term_handler(void)
922 struct tevent_signal *se;
924 se = tevent_add_signal(smbd_event_context(),
925 smbd_event_context(),
926 SIGTERM, 0,
927 smbd_sig_term_handler,
928 NULL);
929 if (!se) {
930 exit_server("failed to setup SIGTERM handler");
934 static void smbd_sig_hup_handler(struct tevent_context *ev,
935 struct tevent_signal *se,
936 int signum,
937 int count,
938 void *siginfo,
939 void *private_data)
941 struct messaging_context *msg_ctx = talloc_get_type_abort(
942 private_data, struct messaging_context);
943 change_to_root_user();
944 DEBUG(1,("Reloading services after SIGHUP\n"));
945 reload_services(msg_ctx, smbd_server_conn->sock, False);
946 if (am_parent) {
947 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
951 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
952 struct messaging_context *msg_ctx)
954 struct tevent_signal *se;
956 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
957 msg_ctx);
958 if (!se) {
959 exit_server("failed to setup SIGHUP handler");
963 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
965 fd_set r_fds, w_fds;
966 int selrtn = 0;
967 struct timeval to;
968 int maxfd = 0;
970 to.tv_sec = SMBD_SELECT_TIMEOUT;
971 to.tv_usec = 0;
974 * Setup the select fd sets.
977 FD_ZERO(&r_fds);
978 FD_ZERO(&w_fds);
981 * Are there any timed events waiting ? If so, ensure we don't
982 * select for longer than it would take to wait for them.
985 event_add_to_select_args(smbd_event_context(),
986 &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)
2229 if (last_smb_conf_reload_time == 0) {
2230 last_smb_conf_reload_time = t;
2233 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2234 reload_services(sconn->msg_ctx, sconn->sock, True);
2235 last_smb_conf_reload_time = t;
2239 static bool fd_is_readable(int fd)
2241 fd_set fds;
2242 struct timeval timeout = {0, };
2243 int ret;
2245 FD_ZERO(&fds);
2246 FD_SET(fd, &fds);
2248 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2249 if (ret == -1) {
2250 return false;
2252 return FD_ISSET(fd, &fds);
2255 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2257 /* TODO: make write nonblocking */
2260 static void smbd_server_connection_read_handler(
2261 struct smbd_server_connection *conn, int fd)
2263 uint8_t *inbuf = NULL;
2264 size_t inbuf_len = 0;
2265 size_t unread_bytes = 0;
2266 bool encrypted = false;
2267 TALLOC_CTX *mem_ctx = talloc_tos();
2268 NTSTATUS status;
2269 uint32_t seqnum;
2271 bool from_client = (conn->sock == fd);
2273 if (from_client) {
2274 smbd_lock_socket(conn);
2276 if (!fd_is_readable(fd)) {
2277 DEBUG(10,("the echo listener was faster\n"));
2278 smbd_unlock_socket(conn);
2279 return;
2282 /* TODO: make this completely nonblocking */
2283 status = receive_smb_talloc(mem_ctx, conn,
2284 (char **)(void *)&inbuf,
2285 0, /* timeout */
2286 &unread_bytes,
2287 &encrypted,
2288 &inbuf_len, &seqnum,
2289 false /* trusted channel */);
2290 smbd_unlock_socket(conn);
2291 } else {
2292 /* TODO: make this completely nonblocking */
2293 status = receive_smb_talloc(mem_ctx, conn,
2294 (char **)(void *)&inbuf,
2295 0, /* timeout */
2296 &unread_bytes,
2297 &encrypted,
2298 &inbuf_len, &seqnum,
2299 true /* trusted channel */);
2302 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2303 goto process;
2305 if (NT_STATUS_IS_ERR(status)) {
2306 exit_server_cleanly("failed to receive smb request");
2308 if (!NT_STATUS_IS_OK(status)) {
2309 return;
2312 process:
2313 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2314 seqnum, encrypted, NULL);
2317 static void smbd_server_connection_handler(struct event_context *ev,
2318 struct fd_event *fde,
2319 uint16_t flags,
2320 void *private_data)
2322 struct smbd_server_connection *conn = talloc_get_type(private_data,
2323 struct smbd_server_connection);
2325 if (flags & EVENT_FD_WRITE) {
2326 smbd_server_connection_write_handler(conn);
2327 return;
2329 if (flags & EVENT_FD_READ) {
2330 smbd_server_connection_read_handler(conn, conn->sock);
2331 return;
2335 static void smbd_server_echo_handler(struct event_context *ev,
2336 struct fd_event *fde,
2337 uint16_t flags,
2338 void *private_data)
2340 struct smbd_server_connection *conn = talloc_get_type(private_data,
2341 struct smbd_server_connection);
2343 if (flags & EVENT_FD_WRITE) {
2344 smbd_server_connection_write_handler(conn);
2345 return;
2347 if (flags & EVENT_FD_READ) {
2348 smbd_server_connection_read_handler(
2349 conn, conn->smb1.echo_handler.trusted_fd);
2350 return;
2354 /****************************************************************************
2355 received when we should release a specific IP
2356 ****************************************************************************/
2357 static void release_ip(const char *ip, void *priv)
2359 const char *addr = (const char *)priv;
2360 const char *p = addr;
2362 if (strncmp("::ffff:", addr, 7) == 0) {
2363 p = addr + 7;
2366 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2367 /* we can't afford to do a clean exit - that involves
2368 database writes, which would potentially mean we
2369 are still running after the failover has finished -
2370 we have to get rid of this process ID straight
2371 away */
2372 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2373 ip));
2374 /* note we must exit with non-zero status so the unclean handler gets
2375 called in the parent, so that the brl database is tickled */
2376 _exit(1);
2380 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2381 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2383 struct smbd_server_connection *sconn = talloc_get_type_abort(
2384 private_data, struct smbd_server_connection);
2386 release_ip((char *)data->data, sconn->client_id.addr);
2389 #ifdef CLUSTER_SUPPORT
2390 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2391 struct sockaddr_storage *client)
2393 socklen_t length;
2394 length = sizeof(*server);
2395 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2396 return -1;
2398 length = sizeof(*client);
2399 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2400 return -1;
2402 return 0;
2404 #endif
2407 * Send keepalive packets to our client
2409 static bool keepalive_fn(const struct timeval *now, void *private_data)
2411 struct smbd_server_connection *sconn = smbd_server_conn;
2412 bool ret;
2414 if (sconn->using_smb2) {
2415 /* Don't do keepalives on an SMB2 connection. */
2416 return false;
2419 smbd_lock_socket(smbd_server_conn);
2420 ret = send_keepalive(sconn->sock);
2421 smbd_unlock_socket(smbd_server_conn);
2423 if (!ret) {
2424 char addr[INET6_ADDRSTRLEN];
2426 * Try and give an error message saying what
2427 * client failed.
2429 DEBUG(0, ("send_keepalive failed for client %s. "
2430 "Error %s - exiting\n",
2431 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2432 strerror(errno)));
2433 return False;
2435 return True;
2439 * Do the recurring check if we're idle
2441 static bool deadtime_fn(const struct timeval *now, void *private_data)
2443 struct smbd_server_connection *sconn =
2444 (struct smbd_server_connection *)private_data;
2446 if ((conn_num_open(sconn) == 0)
2447 || (conn_idle_all(sconn, now->tv_sec))) {
2448 DEBUG( 2, ( "Closing idle connection\n" ) );
2449 messaging_send(sconn->msg_ctx,
2450 messaging_server_id(sconn->msg_ctx),
2451 MSG_SHUTDOWN, &data_blob_null);
2452 return False;
2455 return True;
2459 * Do the recurring log file and smb.conf reload checks.
2462 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2464 struct smbd_server_connection *sconn = talloc_get_type_abort(
2465 private_data, struct smbd_server_connection);
2467 DEBUG(5, ("housekeeping\n"));
2469 change_to_root_user();
2471 /* update printer queue caches if necessary */
2472 update_monitored_printq_cache(sconn->msg_ctx);
2474 /* check if we need to reload services */
2475 check_reload(sconn, time_mono(NULL));
2477 /* Change machine password if neccessary. */
2478 attempt_machine_password_change();
2481 * Force a log file check.
2483 force_check_log_size();
2484 check_log_size();
2485 return true;
2488 static int create_unlink_tmp(const char *dir)
2490 char *fname;
2491 int fd;
2493 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2494 if (fname == NULL) {
2495 errno = ENOMEM;
2496 return -1;
2498 fd = mkstemp(fname);
2499 if (fd == -1) {
2500 TALLOC_FREE(fname);
2501 return -1;
2503 if (unlink(fname) == -1) {
2504 int sys_errno = errno;
2505 close(fd);
2506 TALLOC_FREE(fname);
2507 errno = sys_errno;
2508 return -1;
2510 TALLOC_FREE(fname);
2511 return fd;
2514 struct smbd_echo_state {
2515 struct tevent_context *ev;
2516 struct iovec *pending;
2517 struct smbd_server_connection *sconn;
2518 int parent_pipe;
2520 struct tevent_fd *parent_fde;
2522 struct tevent_fd *read_fde;
2523 struct tevent_req *write_req;
2526 static void smbd_echo_writer_done(struct tevent_req *req);
2528 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2530 int num_pending;
2532 if (state->write_req != NULL) {
2533 return;
2536 num_pending = talloc_array_length(state->pending);
2537 if (num_pending == 0) {
2538 return;
2541 state->write_req = writev_send(state, state->ev, NULL,
2542 state->parent_pipe, false,
2543 state->pending, num_pending);
2544 if (state->write_req == NULL) {
2545 DEBUG(1, ("writev_send failed\n"));
2546 exit(1);
2549 talloc_steal(state->write_req, state->pending);
2550 state->pending = NULL;
2552 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2553 state);
2556 static void smbd_echo_writer_done(struct tevent_req *req)
2558 struct smbd_echo_state *state = tevent_req_callback_data(
2559 req, struct smbd_echo_state);
2560 ssize_t written;
2561 int err;
2563 written = writev_recv(req, &err);
2564 TALLOC_FREE(req);
2565 state->write_req = NULL;
2566 if (written == -1) {
2567 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2568 exit(1);
2570 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2571 smbd_echo_activate_writer(state);
2574 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2575 uint32_t seqnum)
2577 struct smb_request req;
2578 uint16_t num_replies;
2579 size_t out_len;
2580 char *outbuf;
2581 bool ok;
2583 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2584 DEBUG(10, ("Got netbios keepalive\n"));
2586 * Just swallow it
2588 return true;
2591 if (inbuf_len < smb_size) {
2592 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2593 return false;
2595 if (!valid_smb_header(inbuf)) {
2596 DEBUG(10, ("Got invalid SMB header\n"));
2597 return false;
2600 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2601 seqnum)) {
2602 return false;
2604 req.inbuf = inbuf;
2606 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2607 smb_messages[req.cmd].name
2608 ? smb_messages[req.cmd].name : "unknown"));
2610 if (req.cmd != SMBecho) {
2611 return false;
2613 if (req.wct < 1) {
2614 return false;
2617 num_replies = SVAL(req.vwv+0, 0);
2618 if (num_replies != 1) {
2619 /* Not a Windows "Hey, you're still there?" request */
2620 return false;
2623 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2624 1, req.buflen)) {
2625 DEBUG(10, ("create_outbuf failed\n"));
2626 return false;
2628 req.outbuf = (uint8_t *)outbuf;
2630 SSVAL(req.outbuf, smb_vwv0, num_replies);
2632 if (req.buflen > 0) {
2633 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2636 out_len = smb_len(req.outbuf) + 4;
2638 ok = srv_send_smb(req.sconn,
2639 (char *)outbuf,
2640 true, seqnum+1,
2641 false, &req.pcd);
2642 TALLOC_FREE(outbuf);
2643 if (!ok) {
2644 exit(1);
2647 return true;
2650 static void smbd_echo_exit(struct tevent_context *ev,
2651 struct tevent_fd *fde, uint16_t flags,
2652 void *private_data)
2654 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2655 exit(0);
2658 static void smbd_echo_reader(struct tevent_context *ev,
2659 struct tevent_fd *fde, uint16_t flags,
2660 void *private_data)
2662 struct smbd_echo_state *state = talloc_get_type_abort(
2663 private_data, struct smbd_echo_state);
2664 struct smbd_server_connection *sconn = state->sconn;
2665 size_t unread, num_pending;
2666 NTSTATUS status;
2667 struct iovec *tmp;
2668 size_t iov_len;
2669 uint32_t seqnum = 0;
2670 bool reply;
2671 bool ok;
2672 bool encrypted = false;
2674 smb_msleep(1000);
2676 ok = smbd_lock_socket_internal(sconn);
2677 if (!ok) {
2678 DEBUG(0, ("%s: failed to lock socket\n",
2679 __location__));
2680 exit(1);
2683 if (!fd_is_readable(sconn->sock)) {
2684 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2685 (int)sys_getpid()));
2686 ok = smbd_unlock_socket_internal(sconn);
2687 if (!ok) {
2688 DEBUG(1, ("%s: failed to unlock socket in\n",
2689 __location__));
2690 exit(1);
2692 return;
2695 num_pending = talloc_array_length(state->pending);
2696 tmp = talloc_realloc(state, state->pending, struct iovec,
2697 num_pending+1);
2698 if (tmp == NULL) {
2699 DEBUG(1, ("talloc_realloc failed\n"));
2700 exit(1);
2702 state->pending = tmp;
2704 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2706 status = receive_smb_talloc(state->pending, sconn,
2707 (char **)(void *)&state->pending[num_pending].iov_base,
2708 0 /* timeout */,
2709 &unread,
2710 &encrypted,
2711 &iov_len,
2712 &seqnum,
2713 false /* trusted_channel*/);
2714 if (!NT_STATUS_IS_OK(status)) {
2715 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2716 (int)sys_getpid(), nt_errstr(status)));
2717 exit(1);
2719 state->pending[num_pending].iov_len = iov_len;
2721 ok = smbd_unlock_socket_internal(sconn);
2722 if (!ok) {
2723 DEBUG(1, ("%s: failed to unlock socket in\n",
2724 __location__));
2725 exit(1);
2728 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2729 state->pending[num_pending].iov_len,
2730 seqnum);
2731 if (reply) {
2732 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2733 /* no check, shrinking by some bytes does not fail */
2734 state->pending = talloc_realloc(state, state->pending,
2735 struct iovec,
2736 num_pending);
2737 return;
2740 if (state->pending[num_pending].iov_len >= smb_size) {
2742 * place the seqnum in the packet so that the main process
2743 * can reply with signing
2745 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2746 smb_ss_field, seqnum);
2747 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2748 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2751 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2752 smbd_echo_activate_writer(state);
2755 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2756 int parent_pipe)
2758 struct smbd_echo_state *state;
2760 state = talloc_zero(sconn, struct smbd_echo_state);
2761 if (state == NULL) {
2762 DEBUG(1, ("talloc failed\n"));
2763 return;
2765 state->sconn = sconn;
2766 state->parent_pipe = parent_pipe;
2767 state->ev = s3_tevent_context_init(state);
2768 if (state->ev == NULL) {
2769 DEBUG(1, ("tevent_context_init failed\n"));
2770 TALLOC_FREE(state);
2771 return;
2773 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2774 TEVENT_FD_READ, smbd_echo_exit,
2775 state);
2776 if (state->parent_fde == NULL) {
2777 DEBUG(1, ("tevent_add_fd failed\n"));
2778 TALLOC_FREE(state);
2779 return;
2781 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2782 TEVENT_FD_READ, smbd_echo_reader,
2783 state);
2784 if (state->read_fde == NULL) {
2785 DEBUG(1, ("tevent_add_fd failed\n"));
2786 TALLOC_FREE(state);
2787 return;
2790 while (true) {
2791 if (tevent_loop_once(state->ev) == -1) {
2792 DEBUG(1, ("tevent_loop_once failed: %s\n",
2793 strerror(errno)));
2794 break;
2797 TALLOC_FREE(state);
2801 * Handle SMBecho requests in a forked child process
2803 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2805 int listener_pipe[2];
2806 int res;
2807 pid_t child;
2809 res = pipe(listener_pipe);
2810 if (res == -1) {
2811 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2812 return false;
2814 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2815 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2816 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2817 goto fail;
2820 child = sys_fork();
2821 if (child == 0) {
2822 NTSTATUS status;
2824 close(listener_pipe[0]);
2825 set_blocking(listener_pipe[1], false);
2827 status = reinit_after_fork(sconn->msg_ctx,
2828 smbd_event_context(),
2829 procid_self(), false);
2830 if (!NT_STATUS_IS_OK(status)) {
2831 DEBUG(1, ("reinit_after_fork failed: %s\n",
2832 nt_errstr(status)));
2833 exit(1);
2835 smbd_echo_loop(sconn, listener_pipe[1]);
2836 exit(0);
2838 close(listener_pipe[1]);
2839 listener_pipe[1] = -1;
2840 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2842 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2845 * Without smb signing this is the same as the normal smbd
2846 * listener. This needs to change once signing comes in.
2848 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2849 sconn,
2850 sconn->smb1.echo_handler.trusted_fd,
2851 EVENT_FD_READ,
2852 smbd_server_echo_handler,
2853 sconn);
2854 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2855 DEBUG(1, ("event_add_fd failed\n"));
2856 goto fail;
2859 return true;
2861 fail:
2862 if (listener_pipe[0] != -1) {
2863 close(listener_pipe[0]);
2865 if (listener_pipe[1] != -1) {
2866 close(listener_pipe[1]);
2868 sconn->smb1.echo_handler.trusted_fd = -1;
2869 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2870 close(sconn->smb1.echo_handler.socket_lock_fd);
2872 sconn->smb1.echo_handler.trusted_fd = -1;
2873 sconn->smb1.echo_handler.socket_lock_fd = -1;
2874 return false;
2877 #if CLUSTER_SUPPORT
2879 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2880 struct sockaddr_storage *srv,
2881 struct sockaddr_storage *clnt)
2883 struct ctdbd_connection *cconn;
2884 char tmp_addr[INET6_ADDRSTRLEN];
2885 char *addr;
2887 cconn = messaging_ctdbd_connection();
2888 if (cconn == NULL) {
2889 return NT_STATUS_NO_MEMORY;
2892 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2893 addr = talloc_strdup(cconn, tmp_addr);
2894 if (addr == NULL) {
2895 return NT_STATUS_NO_MEMORY;
2897 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2900 #endif
2902 /****************************************************************************
2903 Process commands from the client
2904 ****************************************************************************/
2906 void smbd_process(struct smbd_server_connection *sconn)
2908 TALLOC_CTX *frame = talloc_stackframe();
2909 struct sockaddr_storage ss;
2910 struct sockaddr *sa = NULL;
2911 socklen_t sa_socklen;
2912 struct tsocket_address *local_address = NULL;
2913 struct tsocket_address *remote_address = NULL;
2914 const char *remaddr = NULL;
2915 int ret;
2917 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2918 lp_security() != SEC_SHARE &&
2919 !lp_async_smb_echo_handler()) {
2921 * We're not making the desion here,
2922 * we're just allowing the client
2923 * to decide between SMB1 and SMB2
2924 * with the first negprot
2925 * packet.
2927 sconn->using_smb2 = true;
2930 /* Ensure child is set to blocking mode */
2931 set_blocking(sconn->sock,True);
2933 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2934 set_socket_options(sconn->sock, lp_socket_options());
2936 sa = (struct sockaddr *)(void *)&ss;
2937 sa_socklen = sizeof(ss);
2938 ret = getpeername(sconn->sock, sa, &sa_socklen);
2939 if (ret != 0) {
2940 int level = (errno == ENOTCONN)?2:0;
2941 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2942 exit_server_cleanly("getpeername() failed.\n");
2944 ret = tsocket_address_bsd_from_sockaddr(sconn,
2945 sa, sa_socklen,
2946 &remote_address);
2947 if (ret != 0) {
2948 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2949 __location__, strerror(errno)));
2950 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2953 sa = (struct sockaddr *)(void *)&ss;
2954 sa_socklen = sizeof(ss);
2955 ret = getsockname(sconn->sock, sa, &sa_socklen);
2956 if (ret != 0) {
2957 int level = (errno == ENOTCONN)?2:0;
2958 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2959 exit_server_cleanly("getsockname() failed.\n");
2961 ret = tsocket_address_bsd_from_sockaddr(sconn,
2962 sa, sa_socklen,
2963 &local_address);
2964 if (ret != 0) {
2965 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2966 __location__, strerror(errno)));
2967 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2970 sconn->local_address = local_address;
2971 sconn->remote_address = remote_address;
2973 if (tsocket_address_is_inet(remote_address, "ip")) {
2974 remaddr = tsocket_address_inet_addr_string(
2975 sconn->remote_address,
2976 talloc_tos());
2977 if (remaddr == NULL) {
2980 } else {
2981 remaddr = "0.0.0.0";
2984 /* this is needed so that we get decent entries
2985 in smbstatus for port 445 connects */
2986 set_remote_machine_name(remaddr, false);
2987 reload_services(sconn->msg_ctx, sconn->sock, true);
2990 * Before the first packet, check the global hosts allow/ hosts deny
2991 * parameters before doing any parsing of packets passed to us by the
2992 * client. This prevents attacks on our parsing code from hosts not in
2993 * the hosts allow list.
2996 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2997 sconn->client_id.name,
2998 sconn->client_id.addr)) {
3000 * send a negative session response "not listening on calling
3001 * name"
3003 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3004 DEBUG( 1, ("Connection denied from %s to %s\n",
3005 tsocket_address_string(remote_address, talloc_tos()),
3006 tsocket_address_string(local_address, talloc_tos())));
3007 (void)srv_send_smb(sconn,(char *)buf, false,
3008 0, false, NULL);
3009 exit_server_cleanly("connection denied");
3012 DEBUG(10, ("Connection allowed from %s to %s\n",
3013 tsocket_address_string(remote_address, talloc_tos()),
3014 tsocket_address_string(local_address, talloc_tos())));
3016 init_modules();
3018 smb_perfcount_init();
3020 if (!init_account_policy()) {
3021 exit_server("Could not open account policy tdb.\n");
3024 if (*lp_rootdir()) {
3025 if (chroot(lp_rootdir()) != 0) {
3026 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3027 exit_server("Failed to chroot()");
3029 if (chdir("/") == -1) {
3030 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3031 exit_server("Failed to chroot()");
3033 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3036 if (!srv_init_signing(sconn)) {
3037 exit_server("Failed to init smb_signing");
3040 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3041 exit_server("Failed to fork echo handler");
3044 /* Setup oplocks */
3045 if (!init_oplocks(sconn->msg_ctx))
3046 exit_server("Failed to init oplocks");
3048 /* register our message handlers */
3049 messaging_register(sconn->msg_ctx, NULL,
3050 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3051 messaging_register(sconn->msg_ctx, sconn,
3052 MSG_SMB_RELEASE_IP, msg_release_ip);
3053 messaging_register(sconn->msg_ctx, NULL,
3054 MSG_SMB_CLOSE_FILE, msg_close_file);
3057 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3058 * MSGs to all child processes
3060 messaging_deregister(sconn->msg_ctx,
3061 MSG_DEBUG, NULL);
3062 messaging_register(sconn->msg_ctx, NULL,
3063 MSG_DEBUG, debug_message);
3065 if ((lp_keepalive() != 0)
3066 && !(event_add_idle(smbd_event_context(), NULL,
3067 timeval_set(lp_keepalive(), 0),
3068 "keepalive", keepalive_fn,
3069 NULL))) {
3070 DEBUG(0, ("Could not add keepalive event\n"));
3071 exit(1);
3074 if (!(event_add_idle(smbd_event_context(), NULL,
3075 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3076 "deadtime", deadtime_fn, sconn))) {
3077 DEBUG(0, ("Could not add deadtime event\n"));
3078 exit(1);
3081 if (!(event_add_idle(smbd_event_context(), NULL,
3082 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3083 "housekeeping", housekeeping_fn, sconn))) {
3084 DEBUG(0, ("Could not add housekeeping event\n"));
3085 exit(1);
3088 #ifdef CLUSTER_SUPPORT
3090 if (lp_clustering()) {
3092 * We need to tell ctdb about our client's TCP
3093 * connection, so that for failover ctdbd can send
3094 * tickle acks, triggering a reconnection by the
3095 * client.
3098 struct sockaddr_storage srv, clnt;
3100 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3101 NTSTATUS status;
3102 status = smbd_register_ips(sconn, &srv, &clnt);
3103 if (!NT_STATUS_IS_OK(status)) {
3104 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3105 nt_errstr(status)));
3107 } else
3109 DEBUG(0,("Unable to get tcp info for "
3110 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3111 strerror(errno)));
3115 #endif
3117 sconn->nbt.got_session = false;
3119 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3121 sconn->smb1.sessions.done_sesssetup = false;
3122 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3123 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3124 /* users from session setup */
3125 sconn->smb1.sessions.session_userlist = NULL;
3126 /* workgroup from session setup. */
3127 sconn->smb1.sessions.session_workgroup = NULL;
3128 /* this holds info on user ids that are already validated for this VC */
3129 sconn->smb1.sessions.validated_users = NULL;
3130 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3131 sconn->smb1.sessions.num_validated_vuids = 0;
3133 conn_init(sconn);
3134 if (!init_dptrs(sconn)) {
3135 exit_server("init_dptrs() failed");
3138 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3139 sconn,
3140 sconn->sock,
3141 EVENT_FD_READ,
3142 smbd_server_connection_handler,
3143 sconn);
3144 if (!sconn->smb1.fde) {
3145 exit_server("failed to create smbd_server_connection fde");
3148 TALLOC_FREE(frame);
3150 while (True) {
3151 NTSTATUS status;
3153 frame = talloc_stackframe_pool(8192);
3155 errno = 0;
3157 status = smbd_server_connection_loop_once(sconn);
3158 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3159 !NT_STATUS_IS_OK(status)) {
3160 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3161 " exiting\n", nt_errstr(status)));
3162 break;
3165 TALLOC_FREE(frame);
3168 exit_server_cleanly(NULL);
3171 bool req_is_in_chain(struct smb_request *req)
3173 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3175 * We're right now handling a subsequent request, so we must
3176 * be in a chain
3178 return true;
3181 if (!is_andx_req(req->cmd)) {
3182 return false;
3185 if (req->wct < 2) {
3187 * Okay, an illegal request, but definitely not chained :-)
3189 return false;
3192 return (CVAL(req->vwv+0, 0) != 0xFF);