Part 2 of fix for bug #8998 - Notify code can miss a ChDir.
[Samba.git] / source3 / smbd / process.c
blob5aa19cbee0d7c1471ef9dfad278b5ad2e70d86f7
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/pcap.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
39 extern bool global_machine_password_needs_changing;
41 static void construct_reply_common(struct smb_request *req, const char *inbuf,
42 char *outbuf);
43 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
45 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
47 bool ok;
49 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
50 return true;
53 sconn->smb1.echo_handler.ref_count++;
55 if (sconn->smb1.echo_handler.ref_count > 1) {
56 return true;
59 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
61 do {
62 ok = fcntl_lock(
63 sconn->smb1.echo_handler.socket_lock_fd,
64 SMB_F_SETLKW, 0, 0, F_WRLCK);
65 } while (!ok && (errno == EINTR));
67 if (!ok) {
68 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
69 return false;
72 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
74 return true;
77 void smbd_lock_socket(struct smbd_server_connection *sconn)
79 if (!smbd_lock_socket_internal(sconn)) {
80 exit_server_cleanly("failed to lock socket");
84 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
86 bool ok;
88 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
89 return true;
92 sconn->smb1.echo_handler.ref_count--;
94 if (sconn->smb1.echo_handler.ref_count > 0) {
95 return true;
98 do {
99 ok = fcntl_lock(
100 sconn->smb1.echo_handler.socket_lock_fd,
101 SMB_F_SETLKW, 0, 0, F_UNLCK);
102 } while (!ok && (errno == EINTR));
104 if (!ok) {
105 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
106 return false;
109 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
111 return true;
114 void smbd_unlock_socket(struct smbd_server_connection *sconn)
116 if (!smbd_unlock_socket_internal(sconn)) {
117 exit_server_cleanly("failed to unlock socket");
121 /* Accessor function for smb_read_error for smbd functions. */
123 /****************************************************************************
124 Send an smb to a fd.
125 ****************************************************************************/
127 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
128 bool do_signing, uint32_t seqnum,
129 bool do_encrypt,
130 struct smb_perfcount_data *pcd)
132 size_t len = 0;
133 size_t nwritten=0;
134 ssize_t ret;
135 char *buf_out = buffer;
137 smbd_lock_socket(sconn);
139 if (do_signing) {
140 /* Sign the outgoing packet if required. */
141 srv_calculate_sign_mac(sconn, buf_out, seqnum);
144 if (do_encrypt) {
145 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
146 if (!NT_STATUS_IS_OK(status)) {
147 DEBUG(0, ("send_smb: SMB encryption failed "
148 "on outgoing packet! Error %s\n",
149 nt_errstr(status) ));
150 goto out;
154 len = smb_len(buf_out) + 4;
156 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
157 if (ret <= 0) {
159 char addr[INET6_ADDRSTRLEN];
161 * Try and give an error message saying what
162 * client failed.
164 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
165 (int)sys_getpid(), (int)len,
166 get_peer_addr(sconn->sock, addr, sizeof(addr)),
167 (int)ret, strerror(errno) ));
169 srv_free_enc_buffer(buf_out);
170 goto out;
173 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
174 srv_free_enc_buffer(buf_out);
175 out:
176 SMB_PERFCOUNT_END(pcd);
178 smbd_unlock_socket(sconn);
179 return true;
182 /*******************************************************************
183 Setup the word count and byte count for a smb message.
184 ********************************************************************/
186 int srv_set_message(char *buf,
187 int num_words,
188 int num_bytes,
189 bool zero)
191 if (zero && (num_words || num_bytes)) {
192 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
194 SCVAL(buf,smb_wct,num_words);
195 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
196 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
197 return (smb_size + num_words*2 + num_bytes);
200 static bool valid_smb_header(const uint8_t *inbuf)
202 if (is_encrypted_packet(inbuf)) {
203 return true;
206 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
207 * but it just looks weird to call strncmp for this one.
209 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
212 /* Socket functions for smbd packet processing. */
214 static bool valid_packet_size(size_t len)
217 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
218 * of header. Don't print the error if this fits.... JRA.
221 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
222 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
223 (unsigned long)len));
224 return false;
226 return true;
229 static NTSTATUS read_packet_remainder(int fd, char *buffer,
230 unsigned int timeout, ssize_t len)
232 NTSTATUS status;
234 if (len <= 0) {
235 return NT_STATUS_OK;
238 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
239 if (!NT_STATUS_IS_OK(status)) {
240 char addr[INET6_ADDRSTRLEN];
241 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
242 "error = %s.\n",
243 get_peer_addr(fd, addr, sizeof(addr)),
244 nt_errstr(status)));
246 return status;
249 /****************************************************************************
250 Attempt a zerocopy writeX read. We know here that len > smb_size-4
251 ****************************************************************************/
254 * Unfortunately, earlier versions of smbclient/libsmbclient
255 * don't send this "standard" writeX header. I've fixed this
256 * for 3.2 but we'll use the old method with earlier versions.
257 * Windows and CIFSFS at least use this standard size. Not
258 * sure about MacOSX.
261 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
262 (2*14) + /* word count (including bcc) */ \
263 1 /* pad byte */)
265 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
266 const char lenbuf[4],
267 struct smbd_server_connection *sconn,
268 int sock,
269 char **buffer,
270 unsigned int timeout,
271 size_t *p_unread,
272 size_t *len_ret)
274 /* Size of a WRITEX call (+4 byte len). */
275 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
276 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
277 ssize_t toread;
278 NTSTATUS status;
280 memcpy(writeX_header, lenbuf, 4);
282 status = read_fd_with_timeout(
283 sock, writeX_header + 4,
284 STANDARD_WRITE_AND_X_HEADER_SIZE,
285 STANDARD_WRITE_AND_X_HEADER_SIZE,
286 timeout, NULL);
288 if (!NT_STATUS_IS_OK(status)) {
289 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
290 "error = %s.\n", sconn->client_id.addr,
291 nt_errstr(status)));
292 return status;
296 * Ok - now try and see if this is a possible
297 * valid writeX call.
300 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
302 * If the data offset is beyond what
303 * we've read, drain the extra bytes.
305 uint16_t doff = SVAL(writeX_header,smb_vwv11);
306 ssize_t newlen;
308 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
309 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
310 if (drain_socket(sock, drain) != drain) {
311 smb_panic("receive_smb_raw_talloc_partial_read:"
312 " failed to drain pending bytes");
314 } else {
315 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
318 /* Spoof down the length and null out the bcc. */
319 set_message_bcc(writeX_header, 0);
320 newlen = smb_len(writeX_header);
322 /* Copy the header we've written. */
324 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
325 writeX_header,
326 sizeof(writeX_header));
328 if (*buffer == NULL) {
329 DEBUG(0, ("Could not allocate inbuf of length %d\n",
330 (int)sizeof(writeX_header)));
331 return NT_STATUS_NO_MEMORY;
334 /* Work out the remaining bytes. */
335 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
336 *len_ret = newlen + 4;
337 return NT_STATUS_OK;
340 if (!valid_packet_size(len)) {
341 return NT_STATUS_INVALID_PARAMETER;
345 * Not a valid writeX call. Just do the standard
346 * talloc and return.
349 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
351 if (*buffer == NULL) {
352 DEBUG(0, ("Could not allocate inbuf of length %d\n",
353 (int)len+4));
354 return NT_STATUS_NO_MEMORY;
357 /* Copy in what we already read. */
358 memcpy(*buffer,
359 writeX_header,
360 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
361 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
363 if(toread > 0) {
364 status = read_packet_remainder(
365 sock,
366 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
367 timeout, toread);
369 if (!NT_STATUS_IS_OK(status)) {
370 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
371 nt_errstr(status)));
372 return status;
376 *len_ret = len + 4;
377 return NT_STATUS_OK;
380 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
381 struct smbd_server_connection *sconn,
382 int sock,
383 char **buffer, unsigned int timeout,
384 size_t *p_unread, size_t *plen)
386 char lenbuf[4];
387 size_t len;
388 int min_recv_size = lp_min_receive_file_size();
389 NTSTATUS status;
391 *p_unread = 0;
393 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
394 &len);
395 if (!NT_STATUS_IS_OK(status)) {
396 return status;
399 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
400 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
401 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
402 !srv_is_signing_active(sconn) &&
403 sconn->smb1.echo_handler.trusted_fde == NULL) {
405 return receive_smb_raw_talloc_partial_read(
406 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
407 p_unread, plen);
410 if (!valid_packet_size(len)) {
411 return NT_STATUS_INVALID_PARAMETER;
415 * The +4 here can't wrap, we've checked the length above already.
418 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
420 if (*buffer == NULL) {
421 DEBUG(0, ("Could not allocate inbuf of length %d\n",
422 (int)len+4));
423 return NT_STATUS_NO_MEMORY;
426 memcpy(*buffer, lenbuf, sizeof(lenbuf));
428 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
429 if (!NT_STATUS_IS_OK(status)) {
430 return status;
433 *plen = len + 4;
434 return NT_STATUS_OK;
437 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
438 struct smbd_server_connection *sconn,
439 int sock,
440 char **buffer, unsigned int timeout,
441 size_t *p_unread, bool *p_encrypted,
442 size_t *p_len,
443 uint32_t *seqnum,
444 bool trusted_channel)
446 size_t len = 0;
447 NTSTATUS status;
449 *p_encrypted = false;
451 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
452 p_unread, &len);
453 if (!NT_STATUS_IS_OK(status)) {
454 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
455 ("receive_smb_raw_talloc failed for client %s "
456 "read error = %s.\n",
457 sconn->client_id.addr, nt_errstr(status)));
458 return status;
461 if (is_encrypted_packet((uint8_t *)*buffer)) {
462 status = srv_decrypt_buffer(*buffer);
463 if (!NT_STATUS_IS_OK(status)) {
464 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
465 "incoming packet! Error %s\n",
466 nt_errstr(status) ));
467 return status;
469 *p_encrypted = true;
472 /* Check the incoming SMB signature. */
473 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
474 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
475 "incoming packet!\n"));
476 return NT_STATUS_INVALID_NETWORK_RESPONSE;
479 *p_len = len;
480 return NT_STATUS_OK;
484 * Initialize a struct smb_request from an inbuf
487 static bool init_smb_request(struct smb_request *req,
488 struct smbd_server_connection *sconn,
489 const uint8 *inbuf,
490 size_t unread_bytes, bool encrypted,
491 uint32_t seqnum)
493 size_t req_size = smb_len(inbuf) + 4;
494 /* Ensure we have at least smb_size bytes. */
495 if (req_size < smb_size) {
496 DEBUG(0,("init_smb_request: invalid request size %u\n",
497 (unsigned int)req_size ));
498 return false;
500 req->cmd = CVAL(inbuf, smb_com);
501 req->flags2 = SVAL(inbuf, smb_flg2);
502 req->smbpid = SVAL(inbuf, smb_pid);
503 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
504 req->seqnum = seqnum;
505 req->vuid = SVAL(inbuf, smb_uid);
506 req->tid = SVAL(inbuf, smb_tid);
507 req->wct = CVAL(inbuf, smb_wct);
508 req->vwv = (uint16_t *)(inbuf+smb_vwv);
509 req->buflen = smb_buflen(inbuf);
510 req->buf = (const uint8_t *)smb_buf(inbuf);
511 req->unread_bytes = unread_bytes;
512 req->encrypted = encrypted;
513 req->sconn = sconn;
514 req->conn = conn_find(sconn,req->tid);
515 req->chain_fsp = NULL;
516 req->chain_outbuf = NULL;
517 req->done = false;
518 req->smb2req = NULL;
519 smb_init_perfcount_data(&req->pcd);
521 /* Ensure we have at least wct words and 2 bytes of bcc. */
522 if (smb_size + req->wct*2 > req_size) {
523 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
524 (unsigned int)req->wct,
525 (unsigned int)req_size));
526 return false;
528 /* Ensure bcc is correct. */
529 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
530 DEBUG(0,("init_smb_request: invalid bcc number %u "
531 "(wct = %u, size %u)\n",
532 (unsigned int)req->buflen,
533 (unsigned int)req->wct,
534 (unsigned int)req_size));
535 return false;
538 req->outbuf = NULL;
539 return true;
542 static void process_smb(struct smbd_server_connection *conn,
543 uint8_t *inbuf, size_t nread, size_t unread_bytes,
544 uint32_t seqnum, bool encrypted,
545 struct smb_perfcount_data *deferred_pcd);
547 static void smbd_deferred_open_timer(struct event_context *ev,
548 struct timed_event *te,
549 struct timeval _tval,
550 void *private_data)
552 struct pending_message_list *msg = talloc_get_type(private_data,
553 struct pending_message_list);
554 TALLOC_CTX *mem_ctx = talloc_tos();
555 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
556 uint8_t *inbuf;
558 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
559 msg->buf.length);
560 if (inbuf == NULL) {
561 exit_server("smbd_deferred_open_timer: talloc failed\n");
562 return;
565 /* We leave this message on the queue so the open code can
566 know this is a retry. */
567 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
568 (unsigned long long)mid ));
570 /* Mark the message as processed so this is not
571 * re-processed in error. */
572 msg->processed = true;
574 process_smb(smbd_server_conn, inbuf,
575 msg->buf.length, 0,
576 msg->seqnum, msg->encrypted, &msg->pcd);
578 /* If it's still there and was processed, remove it. */
579 msg = get_deferred_open_message_smb(mid);
580 if (msg && msg->processed) {
581 remove_deferred_open_message_smb(mid);
585 /****************************************************************************
586 Function to push a message onto the tail of a linked list of smb messages ready
587 for processing.
588 ****************************************************************************/
590 static bool push_queued_message(struct smb_request *req,
591 struct timeval request_time,
592 struct timeval end_time,
593 char *private_data, size_t private_len)
595 int msg_len = smb_len(req->inbuf) + 4;
596 struct pending_message_list *msg;
598 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
600 if(msg == NULL) {
601 DEBUG(0,("push_message: malloc fail (1)\n"));
602 return False;
605 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
606 if(msg->buf.data == NULL) {
607 DEBUG(0,("push_message: malloc fail (2)\n"));
608 TALLOC_FREE(msg);
609 return False;
612 msg->request_time = request_time;
613 msg->seqnum = req->seqnum;
614 msg->encrypted = req->encrypted;
615 msg->processed = false;
616 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
618 if (private_data) {
619 msg->private_data = data_blob_talloc(msg, private_data,
620 private_len);
621 if (msg->private_data.data == NULL) {
622 DEBUG(0,("push_message: malloc fail (3)\n"));
623 TALLOC_FREE(msg);
624 return False;
628 msg->te = event_add_timed(smbd_event_context(),
629 msg,
630 end_time,
631 smbd_deferred_open_timer,
632 msg);
633 if (!msg->te) {
634 DEBUG(0,("push_message: event_add_timed failed\n"));
635 TALLOC_FREE(msg);
636 return false;
639 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
641 DEBUG(10,("push_message: pushed message length %u on "
642 "deferred_open_queue\n", (unsigned int)msg_len));
644 return True;
647 /****************************************************************************
648 Function to delete a sharing violation open message by mid.
649 ****************************************************************************/
651 void remove_deferred_open_message_smb(uint64_t mid)
653 struct pending_message_list *pml;
655 if (smbd_server_conn->using_smb2) {
656 remove_deferred_open_message_smb2(smbd_server_conn, mid);
657 return;
660 for (pml = deferred_open_queue; pml; pml = pml->next) {
661 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
662 DEBUG(10,("remove_deferred_open_message_smb: "
663 "deleting mid %llu len %u\n",
664 (unsigned long long)mid,
665 (unsigned int)pml->buf.length ));
666 DLIST_REMOVE(deferred_open_queue, pml);
667 TALLOC_FREE(pml);
668 return;
673 /****************************************************************************
674 Move a sharing violation open retry message to the front of the list and
675 schedule it for immediate processing.
676 ****************************************************************************/
678 void schedule_deferred_open_message_smb(uint64_t mid)
680 struct pending_message_list *pml;
681 int i = 0;
683 if (smbd_server_conn->using_smb2) {
684 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
685 return;
688 for (pml = deferred_open_queue; pml; pml = pml->next) {
689 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
691 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
692 "msg_mid = %llu\n",
693 i++,
694 (unsigned long long)msg_mid ));
696 if (mid == msg_mid) {
697 struct timed_event *te;
699 if (pml->processed) {
700 /* A processed message should not be
701 * rescheduled. */
702 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
703 "message mid %llu was already processed\n",
704 (unsigned long long)msg_mid ));
705 continue;
708 DEBUG(10,("schedule_deferred_open_message_smb: "
709 "scheduling mid %llu\n",
710 (unsigned long long)mid ));
712 te = event_add_timed(smbd_event_context(),
713 pml,
714 timeval_zero(),
715 smbd_deferred_open_timer,
716 pml);
717 if (!te) {
718 DEBUG(10,("schedule_deferred_open_message_smb: "
719 "event_add_timed() failed, "
720 "skipping mid %llu\n",
721 (unsigned long long)msg_mid ));
724 TALLOC_FREE(pml->te);
725 pml->te = te;
726 DLIST_PROMOTE(deferred_open_queue, pml);
727 return;
731 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
732 "find message mid %llu\n",
733 (unsigned long long)mid ));
736 /****************************************************************************
737 Return true if this mid is on the deferred queue and was not yet processed.
738 ****************************************************************************/
740 bool open_was_deferred(uint64_t mid)
742 struct pending_message_list *pml;
744 if (smbd_server_conn->using_smb2) {
745 return open_was_deferred_smb2(smbd_server_conn, mid);
748 for (pml = deferred_open_queue; pml; pml = pml->next) {
749 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
750 return True;
753 return False;
756 /****************************************************************************
757 Return the message queued by this mid.
758 ****************************************************************************/
760 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
762 struct pending_message_list *pml;
764 for (pml = deferred_open_queue; pml; pml = pml->next) {
765 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
766 return pml;
769 return NULL;
772 /****************************************************************************
773 Get the state data queued by this mid.
774 ****************************************************************************/
776 bool get_deferred_open_message_state(struct smb_request *smbreq,
777 struct timeval *p_request_time,
778 void **pp_state)
780 struct pending_message_list *pml;
782 if (smbd_server_conn->using_smb2) {
783 return get_deferred_open_message_state_smb2(smbreq->smb2req,
784 p_request_time,
785 pp_state);
788 pml = get_deferred_open_message_smb(smbreq->mid);
789 if (!pml) {
790 return false;
792 if (p_request_time) {
793 *p_request_time = pml->request_time;
795 if (pp_state) {
796 *pp_state = (void *)pml->private_data.data;
798 return true;
801 /****************************************************************************
802 Function to push a deferred open smb message onto a linked list of local smb
803 messages ready for processing.
804 ****************************************************************************/
806 bool push_deferred_open_message_smb(struct smb_request *req,
807 struct timeval request_time,
808 struct timeval timeout,
809 struct file_id id,
810 char *private_data, size_t priv_len)
812 struct timeval end_time;
814 if (req->smb2req) {
815 return push_deferred_open_message_smb2(req->smb2req,
816 request_time,
817 timeout,
819 private_data,
820 priv_len);
823 if (req->unread_bytes) {
824 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
825 "unread_bytes = %u\n",
826 (unsigned int)req->unread_bytes ));
827 smb_panic("push_deferred_open_message_smb: "
828 "logic error unread_bytes != 0" );
831 end_time = timeval_sum(&request_time, &timeout);
833 DEBUG(10,("push_deferred_open_message_smb: pushing message "
834 "len %u mid %llu timeout time [%u.%06u]\n",
835 (unsigned int) smb_len(req->inbuf)+4,
836 (unsigned long long)req->mid,
837 (unsigned int)end_time.tv_sec,
838 (unsigned int)end_time.tv_usec));
840 return push_queued_message(req, request_time, end_time,
841 private_data, priv_len);
844 struct idle_event {
845 struct timed_event *te;
846 struct timeval interval;
847 char *name;
848 bool (*handler)(const struct timeval *now, void *private_data);
849 void *private_data;
852 static void smbd_idle_event_handler(struct event_context *ctx,
853 struct timed_event *te,
854 struct timeval now,
855 void *private_data)
857 struct idle_event *event =
858 talloc_get_type_abort(private_data, struct idle_event);
860 TALLOC_FREE(event->te);
862 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
863 event->name, event->te));
865 if (!event->handler(&now, event->private_data)) {
866 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
867 event->name, event->te));
868 /* Don't repeat, delete ourselves */
869 TALLOC_FREE(event);
870 return;
873 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
874 event->name, event->te));
876 event->te = event_add_timed(ctx, event,
877 timeval_sum(&now, &event->interval),
878 smbd_idle_event_handler, event);
880 /* We can't do much but fail here. */
881 SMB_ASSERT(event->te != NULL);
884 struct idle_event *event_add_idle(struct event_context *event_ctx,
885 TALLOC_CTX *mem_ctx,
886 struct timeval interval,
887 const char *name,
888 bool (*handler)(const struct timeval *now,
889 void *private_data),
890 void *private_data)
892 struct idle_event *result;
893 struct timeval now = timeval_current();
895 result = TALLOC_P(mem_ctx, struct idle_event);
896 if (result == NULL) {
897 DEBUG(0, ("talloc failed\n"));
898 return NULL;
901 result->interval = interval;
902 result->handler = handler;
903 result->private_data = private_data;
905 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
906 DEBUG(0, ("talloc failed\n"));
907 TALLOC_FREE(result);
908 return NULL;
911 result->te = event_add_timed(event_ctx, result,
912 timeval_sum(&now, &interval),
913 smbd_idle_event_handler, result);
914 if (result->te == NULL) {
915 DEBUG(0, ("event_add_timed failed\n"));
916 TALLOC_FREE(result);
917 return NULL;
920 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
921 return result;
924 static void smbd_sig_term_handler(struct tevent_context *ev,
925 struct tevent_signal *se,
926 int signum,
927 int count,
928 void *siginfo,
929 void *private_data)
931 exit_server_cleanly("termination signal");
934 void smbd_setup_sig_term_handler(void)
936 struct tevent_signal *se;
938 se = tevent_add_signal(smbd_event_context(),
939 smbd_event_context(),
940 SIGTERM, 0,
941 smbd_sig_term_handler,
942 NULL);
943 if (!se) {
944 exit_server("failed to setup SIGTERM handler");
948 static void smbd_sig_hup_handler(struct tevent_context *ev,
949 struct tevent_signal *se,
950 int signum,
951 int count,
952 void *siginfo,
953 void *private_data)
955 struct messaging_context *msg_ctx = talloc_get_type_abort(
956 private_data, struct messaging_context);
957 change_to_root_user();
958 DEBUG(1,("Reloading services after SIGHUP\n"));
959 reload_services(msg_ctx, smbd_server_conn->sock, False);
960 if (am_parent) {
961 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
965 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
966 struct messaging_context *msg_ctx)
968 struct tevent_signal *se;
970 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
971 msg_ctx);
972 if (!se) {
973 exit_server("failed to setup SIGHUP handler");
977 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
979 int timeout;
980 int num_pfds = 0;
981 int ret;
982 bool retry;
984 timeout = SMBD_SELECT_TIMEOUT * 1000;
987 * Are there any timed events waiting ? If so, ensure we don't
988 * select for longer than it would take to wait for them.
991 event_add_to_poll_args(smbd_event_context(), conn,
992 &conn->pfds, &num_pfds, &timeout);
994 /* Process a signal and timed events now... */
995 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
996 return NT_STATUS_RETRY;
1000 int sav;
1001 START_PROFILE(smbd_idle);
1003 ret = sys_poll(conn->pfds, num_pfds, timeout);
1004 sav = errno;
1006 END_PROFILE(smbd_idle);
1007 errno = sav;
1010 if (ret == -1) {
1011 if (errno == EINTR) {
1012 return NT_STATUS_RETRY;
1014 return map_nt_error_from_unix(errno);
1017 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1018 num_pfds);
1019 if (retry) {
1020 return NT_STATUS_RETRY;
1023 /* Did we timeout ? */
1024 if (ret == 0) {
1025 return NT_STATUS_RETRY;
1028 /* should not be reached */
1029 return NT_STATUS_INTERNAL_ERROR;
1033 * Only allow 5 outstanding trans requests. We're allocating memory, so
1034 * prevent a DoS.
1037 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1039 int count = 0;
1040 for (; list != NULL; list = list->next) {
1042 if (list->mid == mid) {
1043 return NT_STATUS_INVALID_PARAMETER;
1046 count += 1;
1048 if (count > 5) {
1049 return NT_STATUS_INSUFFICIENT_RESOURCES;
1052 return NT_STATUS_OK;
1056 These flags determine some of the permissions required to do an operation
1058 Note that I don't set NEED_WRITE on some write operations because they
1059 are used by some brain-dead clients when printing, and I don't want to
1060 force write permissions on print services.
1062 #define AS_USER (1<<0)
1063 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1064 #define TIME_INIT (1<<2)
1065 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1066 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1067 #define DO_CHDIR (1<<6)
1070 define a list of possible SMB messages and their corresponding
1071 functions. Any message that has a NULL function is unimplemented -
1072 please feel free to contribute implementations!
1074 static const struct smb_message_struct {
1075 const char *name;
1076 void (*fn)(struct smb_request *req);
1077 int flags;
1078 } smb_messages[256] = {
1080 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1081 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1082 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1083 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1084 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1085 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1086 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1087 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1088 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1089 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1090 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1091 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1092 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1093 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1094 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1095 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1096 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1097 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1098 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1099 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1100 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1101 /* 0x15 */ { NULL, NULL, 0 },
1102 /* 0x16 */ { NULL, NULL, 0 },
1103 /* 0x17 */ { NULL, NULL, 0 },
1104 /* 0x18 */ { NULL, NULL, 0 },
1105 /* 0x19 */ { NULL, NULL, 0 },
1106 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1107 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1108 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1109 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1110 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1111 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1112 /* 0x20 */ { "SMBwritec", NULL,0},
1113 /* 0x21 */ { NULL, NULL, 0 },
1114 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1115 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1116 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1117 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1118 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1119 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1120 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1121 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1122 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1123 /* 0x2b */ { "SMBecho",reply_echo,0},
1124 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1125 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1126 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1127 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1128 /* 0x30 */ { NULL, NULL, 0 },
1129 /* 0x31 */ { NULL, NULL, 0 },
1130 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1131 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1132 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1133 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1134 /* 0x36 */ { NULL, NULL, 0 },
1135 /* 0x37 */ { NULL, NULL, 0 },
1136 /* 0x38 */ { NULL, NULL, 0 },
1137 /* 0x39 */ { NULL, NULL, 0 },
1138 /* 0x3a */ { NULL, NULL, 0 },
1139 /* 0x3b */ { NULL, NULL, 0 },
1140 /* 0x3c */ { NULL, NULL, 0 },
1141 /* 0x3d */ { NULL, NULL, 0 },
1142 /* 0x3e */ { NULL, NULL, 0 },
1143 /* 0x3f */ { NULL, NULL, 0 },
1144 /* 0x40 */ { NULL, NULL, 0 },
1145 /* 0x41 */ { NULL, NULL, 0 },
1146 /* 0x42 */ { NULL, NULL, 0 },
1147 /* 0x43 */ { NULL, NULL, 0 },
1148 /* 0x44 */ { NULL, NULL, 0 },
1149 /* 0x45 */ { NULL, NULL, 0 },
1150 /* 0x46 */ { NULL, NULL, 0 },
1151 /* 0x47 */ { NULL, NULL, 0 },
1152 /* 0x48 */ { NULL, NULL, 0 },
1153 /* 0x49 */ { NULL, NULL, 0 },
1154 /* 0x4a */ { NULL, NULL, 0 },
1155 /* 0x4b */ { NULL, NULL, 0 },
1156 /* 0x4c */ { NULL, NULL, 0 },
1157 /* 0x4d */ { NULL, NULL, 0 },
1158 /* 0x4e */ { NULL, NULL, 0 },
1159 /* 0x4f */ { NULL, NULL, 0 },
1160 /* 0x50 */ { NULL, NULL, 0 },
1161 /* 0x51 */ { NULL, NULL, 0 },
1162 /* 0x52 */ { NULL, NULL, 0 },
1163 /* 0x53 */ { NULL, NULL, 0 },
1164 /* 0x54 */ { NULL, NULL, 0 },
1165 /* 0x55 */ { NULL, NULL, 0 },
1166 /* 0x56 */ { NULL, NULL, 0 },
1167 /* 0x57 */ { NULL, NULL, 0 },
1168 /* 0x58 */ { NULL, NULL, 0 },
1169 /* 0x59 */ { NULL, NULL, 0 },
1170 /* 0x5a */ { NULL, NULL, 0 },
1171 /* 0x5b */ { NULL, NULL, 0 },
1172 /* 0x5c */ { NULL, NULL, 0 },
1173 /* 0x5d */ { NULL, NULL, 0 },
1174 /* 0x5e */ { NULL, NULL, 0 },
1175 /* 0x5f */ { NULL, NULL, 0 },
1176 /* 0x60 */ { NULL, NULL, 0 },
1177 /* 0x61 */ { NULL, NULL, 0 },
1178 /* 0x62 */ { NULL, NULL, 0 },
1179 /* 0x63 */ { NULL, NULL, 0 },
1180 /* 0x64 */ { NULL, NULL, 0 },
1181 /* 0x65 */ { NULL, NULL, 0 },
1182 /* 0x66 */ { NULL, NULL, 0 },
1183 /* 0x67 */ { NULL, NULL, 0 },
1184 /* 0x68 */ { NULL, NULL, 0 },
1185 /* 0x69 */ { NULL, NULL, 0 },
1186 /* 0x6a */ { NULL, NULL, 0 },
1187 /* 0x6b */ { NULL, NULL, 0 },
1188 /* 0x6c */ { NULL, NULL, 0 },
1189 /* 0x6d */ { NULL, NULL, 0 },
1190 /* 0x6e */ { NULL, NULL, 0 },
1191 /* 0x6f */ { NULL, NULL, 0 },
1192 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1193 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1194 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1195 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1196 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1197 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1198 /* 0x76 */ { NULL, NULL, 0 },
1199 /* 0x77 */ { NULL, NULL, 0 },
1200 /* 0x78 */ { NULL, NULL, 0 },
1201 /* 0x79 */ { NULL, NULL, 0 },
1202 /* 0x7a */ { NULL, NULL, 0 },
1203 /* 0x7b */ { NULL, NULL, 0 },
1204 /* 0x7c */ { NULL, NULL, 0 },
1205 /* 0x7d */ { NULL, NULL, 0 },
1206 /* 0x7e */ { NULL, NULL, 0 },
1207 /* 0x7f */ { NULL, NULL, 0 },
1208 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1209 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1210 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1211 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1212 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1213 /* 0x85 */ { NULL, NULL, 0 },
1214 /* 0x86 */ { NULL, NULL, 0 },
1215 /* 0x87 */ { NULL, NULL, 0 },
1216 /* 0x88 */ { NULL, NULL, 0 },
1217 /* 0x89 */ { NULL, NULL, 0 },
1218 /* 0x8a */ { NULL, NULL, 0 },
1219 /* 0x8b */ { NULL, NULL, 0 },
1220 /* 0x8c */ { NULL, NULL, 0 },
1221 /* 0x8d */ { NULL, NULL, 0 },
1222 /* 0x8e */ { NULL, NULL, 0 },
1223 /* 0x8f */ { NULL, NULL, 0 },
1224 /* 0x90 */ { NULL, NULL, 0 },
1225 /* 0x91 */ { NULL, NULL, 0 },
1226 /* 0x92 */ { NULL, NULL, 0 },
1227 /* 0x93 */ { NULL, NULL, 0 },
1228 /* 0x94 */ { NULL, NULL, 0 },
1229 /* 0x95 */ { NULL, NULL, 0 },
1230 /* 0x96 */ { NULL, NULL, 0 },
1231 /* 0x97 */ { NULL, NULL, 0 },
1232 /* 0x98 */ { NULL, NULL, 0 },
1233 /* 0x99 */ { NULL, NULL, 0 },
1234 /* 0x9a */ { NULL, NULL, 0 },
1235 /* 0x9b */ { NULL, NULL, 0 },
1236 /* 0x9c */ { NULL, NULL, 0 },
1237 /* 0x9d */ { NULL, NULL, 0 },
1238 /* 0x9e */ { NULL, NULL, 0 },
1239 /* 0x9f */ { NULL, NULL, 0 },
1240 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1241 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1242 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1243 /* 0xa3 */ { NULL, NULL, 0 },
1244 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1245 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1246 /* 0xa6 */ { NULL, NULL, 0 },
1247 /* 0xa7 */ { NULL, NULL, 0 },
1248 /* 0xa8 */ { NULL, NULL, 0 },
1249 /* 0xa9 */ { NULL, NULL, 0 },
1250 /* 0xaa */ { NULL, NULL, 0 },
1251 /* 0xab */ { NULL, NULL, 0 },
1252 /* 0xac */ { NULL, NULL, 0 },
1253 /* 0xad */ { NULL, NULL, 0 },
1254 /* 0xae */ { NULL, NULL, 0 },
1255 /* 0xaf */ { NULL, NULL, 0 },
1256 /* 0xb0 */ { NULL, NULL, 0 },
1257 /* 0xb1 */ { NULL, NULL, 0 },
1258 /* 0xb2 */ { NULL, NULL, 0 },
1259 /* 0xb3 */ { NULL, NULL, 0 },
1260 /* 0xb4 */ { NULL, NULL, 0 },
1261 /* 0xb5 */ { NULL, NULL, 0 },
1262 /* 0xb6 */ { NULL, NULL, 0 },
1263 /* 0xb7 */ { NULL, NULL, 0 },
1264 /* 0xb8 */ { NULL, NULL, 0 },
1265 /* 0xb9 */ { NULL, NULL, 0 },
1266 /* 0xba */ { NULL, NULL, 0 },
1267 /* 0xbb */ { NULL, NULL, 0 },
1268 /* 0xbc */ { NULL, NULL, 0 },
1269 /* 0xbd */ { NULL, NULL, 0 },
1270 /* 0xbe */ { NULL, NULL, 0 },
1271 /* 0xbf */ { NULL, NULL, 0 },
1272 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1273 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1274 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1275 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1276 /* 0xc4 */ { NULL, NULL, 0 },
1277 /* 0xc5 */ { NULL, NULL, 0 },
1278 /* 0xc6 */ { NULL, NULL, 0 },
1279 /* 0xc7 */ { NULL, NULL, 0 },
1280 /* 0xc8 */ { NULL, NULL, 0 },
1281 /* 0xc9 */ { NULL, NULL, 0 },
1282 /* 0xca */ { NULL, NULL, 0 },
1283 /* 0xcb */ { NULL, NULL, 0 },
1284 /* 0xcc */ { NULL, NULL, 0 },
1285 /* 0xcd */ { NULL, NULL, 0 },
1286 /* 0xce */ { NULL, NULL, 0 },
1287 /* 0xcf */ { NULL, NULL, 0 },
1288 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1289 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1290 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1291 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1292 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1293 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1294 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1295 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1296 /* 0xd8 */ { NULL, NULL, 0 },
1297 /* 0xd9 */ { NULL, NULL, 0 },
1298 /* 0xda */ { NULL, NULL, 0 },
1299 /* 0xdb */ { NULL, NULL, 0 },
1300 /* 0xdc */ { NULL, NULL, 0 },
1301 /* 0xdd */ { NULL, NULL, 0 },
1302 /* 0xde */ { NULL, NULL, 0 },
1303 /* 0xdf */ { NULL, NULL, 0 },
1304 /* 0xe0 */ { NULL, NULL, 0 },
1305 /* 0xe1 */ { NULL, NULL, 0 },
1306 /* 0xe2 */ { NULL, NULL, 0 },
1307 /* 0xe3 */ { NULL, NULL, 0 },
1308 /* 0xe4 */ { NULL, NULL, 0 },
1309 /* 0xe5 */ { NULL, NULL, 0 },
1310 /* 0xe6 */ { NULL, NULL, 0 },
1311 /* 0xe7 */ { NULL, NULL, 0 },
1312 /* 0xe8 */ { NULL, NULL, 0 },
1313 /* 0xe9 */ { NULL, NULL, 0 },
1314 /* 0xea */ { NULL, NULL, 0 },
1315 /* 0xeb */ { NULL, NULL, 0 },
1316 /* 0xec */ { NULL, NULL, 0 },
1317 /* 0xed */ { NULL, NULL, 0 },
1318 /* 0xee */ { NULL, NULL, 0 },
1319 /* 0xef */ { NULL, NULL, 0 },
1320 /* 0xf0 */ { NULL, NULL, 0 },
1321 /* 0xf1 */ { NULL, NULL, 0 },
1322 /* 0xf2 */ { NULL, NULL, 0 },
1323 /* 0xf3 */ { NULL, NULL, 0 },
1324 /* 0xf4 */ { NULL, NULL, 0 },
1325 /* 0xf5 */ { NULL, NULL, 0 },
1326 /* 0xf6 */ { NULL, NULL, 0 },
1327 /* 0xf7 */ { NULL, NULL, 0 },
1328 /* 0xf8 */ { NULL, NULL, 0 },
1329 /* 0xf9 */ { NULL, NULL, 0 },
1330 /* 0xfa */ { NULL, NULL, 0 },
1331 /* 0xfb */ { NULL, NULL, 0 },
1332 /* 0xfc */ { NULL, NULL, 0 },
1333 /* 0xfd */ { NULL, NULL, 0 },
1334 /* 0xfe */ { NULL, NULL, 0 },
1335 /* 0xff */ { NULL, NULL, 0 }
1339 /*******************************************************************
1340 allocate and initialize a reply packet
1341 ********************************************************************/
1343 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1344 const char *inbuf, char **outbuf, uint8_t num_words,
1345 uint32_t num_bytes)
1348 * Protect against integer wrap
1350 if ((num_bytes > 0xffffff)
1351 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1352 char *msg;
1353 if (asprintf(&msg, "num_bytes too large: %u",
1354 (unsigned)num_bytes) == -1) {
1355 msg = CONST_DISCARD(char *, "num_bytes too large");
1357 smb_panic(msg);
1360 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1361 smb_size + num_words*2 + num_bytes);
1362 if (*outbuf == NULL) {
1363 return false;
1366 construct_reply_common(req, inbuf, *outbuf);
1367 srv_set_message(*outbuf, num_words, num_bytes, false);
1369 * Zero out the word area, the caller has to take care of the bcc area
1370 * himself
1372 if (num_words != 0) {
1373 memset(*outbuf + smb_vwv0, 0, num_words*2);
1376 return true;
1379 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1381 char *outbuf;
1382 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1383 num_bytes)) {
1384 smb_panic("could not allocate output buffer\n");
1386 req->outbuf = (uint8_t *)outbuf;
1390 /*******************************************************************
1391 Dump a packet to a file.
1392 ********************************************************************/
1394 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1396 int fd, i;
1397 char *fname = NULL;
1398 if (DEBUGLEVEL < 50) {
1399 return;
1402 if (len < 4) len = smb_len(data)+4;
1403 for (i=1;i<100;i++) {
1404 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1405 type ? "req" : "resp") == -1) {
1406 return;
1408 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1409 if (fd != -1 || errno != EEXIST) break;
1411 if (fd != -1) {
1412 ssize_t ret = write(fd, data, len);
1413 if (ret != len)
1414 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1415 close(fd);
1416 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1418 SAFE_FREE(fname);
1421 /****************************************************************************
1422 Prepare everything for calling the actual request function, and potentially
1423 call the request function via the "new" interface.
1425 Return False if the "legacy" function needs to be called, everything is
1426 prepared.
1428 Return True if we're done.
1430 I know this API sucks, but it is the one with the least code change I could
1431 find.
1432 ****************************************************************************/
1434 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1436 int flags;
1437 uint16 session_tag;
1438 connection_struct *conn = NULL;
1439 struct smbd_server_connection *sconn = req->sconn;
1441 errno = 0;
1443 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1444 * so subtract 4 from it. */
1445 if ((size < (smb_size - 4)) ||
1446 !valid_smb_header(req->inbuf)) {
1447 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1448 smb_len(req->inbuf)));
1449 exit_server_cleanly("Non-SMB packet");
1452 if (smb_messages[type].fn == NULL) {
1453 DEBUG(0,("Unknown message type %d!\n",type));
1454 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1455 reply_unknown_new(req, type);
1456 return NULL;
1459 flags = smb_messages[type].flags;
1461 /* In share mode security we must ignore the vuid. */
1462 session_tag = (lp_security() == SEC_SHARE)
1463 ? UID_FIELD_INVALID : req->vuid;
1464 conn = req->conn;
1466 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1467 (int)sys_getpid(), (unsigned long)conn));
1469 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1471 /* Ensure this value is replaced in the incoming packet. */
1472 SSVAL(req->inbuf,smb_uid,session_tag);
1475 * Ensure the correct username is in current_user_info. This is a
1476 * really ugly bugfix for problems with multiple session_setup_and_X's
1477 * being done and allowing %U and %G substitutions to work correctly.
1478 * There is a reason this code is done here, don't move it unless you
1479 * know what you're doing... :-).
1480 * JRA.
1483 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1484 user_struct *vuser = NULL;
1486 sconn->smb1.sessions.last_session_tag = session_tag;
1487 if(session_tag != UID_FIELD_INVALID) {
1488 vuser = get_valid_user_struct(sconn, session_tag);
1489 if (vuser) {
1490 set_current_user_info(
1491 vuser->session_info->sanitized_username,
1492 vuser->session_info->unix_name,
1493 vuser->session_info->info3->base.domain.string);
1498 /* Does this call need to be run as the connected user? */
1499 if (flags & AS_USER) {
1501 /* Does this call need a valid tree connection? */
1502 if (!conn) {
1504 * Amazingly, the error code depends on the command
1505 * (from Samba4).
1507 if (type == SMBntcreateX) {
1508 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1509 } else {
1510 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1512 return NULL;
1515 if (!change_to_user(conn,session_tag)) {
1516 DEBUG(0, ("Error: Could not change to user. Removing "
1517 "deferred open, mid=%llu.\n",
1518 (unsigned long long)req->mid));
1519 reply_force_doserror(req, ERRSRV, ERRbaduid);
1520 return conn;
1523 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1525 /* Does it need write permission? */
1526 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1527 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1528 return conn;
1531 /* IPC services are limited */
1532 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1533 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1534 return conn;
1536 } else {
1537 /* This call needs to be run as root */
1538 change_to_root_user();
1541 /* load service specific parameters */
1542 if (conn) {
1543 if (req->encrypted) {
1544 conn->encrypted_tid = true;
1545 /* encrypted required from now on. */
1546 conn->encrypt_level = Required;
1547 } else if (ENCRYPTION_REQUIRED(conn)) {
1548 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1549 exit_server_cleanly("encryption required "
1550 "on connection");
1551 return conn;
1555 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1556 (flags & (AS_USER|DO_CHDIR)
1557 ?True:False))) {
1558 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1559 return conn;
1561 conn->num_smb_operations++;
1564 /* does this protocol need to be run as guest? */
1565 if ((flags & AS_GUEST)
1566 && (!change_to_guest() ||
1567 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1568 sconn->client_id.name,
1569 sconn->client_id.addr))) {
1570 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1571 return conn;
1574 smb_messages[type].fn(req);
1575 return req->conn;
1578 /****************************************************************************
1579 Construct a reply to the incoming packet.
1580 ****************************************************************************/
1582 static void construct_reply(struct smbd_server_connection *sconn,
1583 char *inbuf, int size, size_t unread_bytes,
1584 uint32_t seqnum, bool encrypted,
1585 struct smb_perfcount_data *deferred_pcd)
1587 connection_struct *conn;
1588 struct smb_request *req;
1590 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1591 smb_panic("could not allocate smb_request");
1594 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1595 encrypted, seqnum)) {
1596 exit_server_cleanly("Invalid SMB request");
1599 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1601 /* we popped this message off the queue - keep original perf data */
1602 if (deferred_pcd)
1603 req->pcd = *deferred_pcd;
1604 else {
1605 SMB_PERFCOUNT_START(&req->pcd);
1606 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1607 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1610 conn = switch_message(req->cmd, req, size);
1612 if (req->unread_bytes) {
1613 /* writeX failed. drain socket. */
1614 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1615 req->unread_bytes) {
1616 smb_panic("failed to drain pending bytes");
1618 req->unread_bytes = 0;
1621 if (req->done) {
1622 TALLOC_FREE(req);
1623 return;
1626 if (req->outbuf == NULL) {
1627 return;
1630 if (CVAL(req->outbuf,0) == 0) {
1631 show_msg((char *)req->outbuf);
1634 if (!srv_send_smb(req->sconn,
1635 (char *)req->outbuf,
1636 true, req->seqnum+1,
1637 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1638 &req->pcd)) {
1639 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1642 TALLOC_FREE(req);
1644 return;
1647 /****************************************************************************
1648 Process an smb from the client
1649 ****************************************************************************/
1650 static void process_smb(struct smbd_server_connection *sconn,
1651 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1652 uint32_t seqnum, bool encrypted,
1653 struct smb_perfcount_data *deferred_pcd)
1655 int msg_type = CVAL(inbuf,0);
1657 DO_PROFILE_INC(smb_count);
1659 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1660 smb_len(inbuf) ) );
1661 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1662 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1664 if (msg_type != 0) {
1666 * NetBIOS session request, keepalive, etc.
1668 reply_special(sconn, (char *)inbuf, nread);
1669 goto done;
1672 if (sconn->using_smb2) {
1673 /* At this point we're not really using smb2,
1674 * we make the decision here.. */
1675 if (smbd_is_smb2_header(inbuf, nread)) {
1676 smbd_smb2_first_negprot(sconn, inbuf, nread);
1677 return;
1678 } else if (nread >= smb_size && valid_smb_header(inbuf)
1679 && CVAL(inbuf, smb_com) != 0x72) {
1680 /* This is a non-negprot SMB1 packet.
1681 Disable SMB2 from now on. */
1682 sconn->using_smb2 = false;
1686 show_msg((char *)inbuf);
1688 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1689 encrypted, deferred_pcd);
1690 sconn->trans_num++;
1692 done:
1693 sconn->num_requests++;
1695 /* The timeout_processing function isn't run nearly
1696 often enough to implement 'max log size' without
1697 overrunning the size of the file by many megabytes.
1698 This is especially true if we are running at debug
1699 level 10. Checking every 50 SMBs is a nice
1700 tradeoff of performance vs log file size overrun. */
1702 if ((sconn->num_requests % 50) == 0 &&
1703 need_to_check_log_size()) {
1704 change_to_root_user();
1705 check_log_size();
1709 /****************************************************************************
1710 Return a string containing the function name of a SMB command.
1711 ****************************************************************************/
1713 const char *smb_fn_name(int type)
1715 const char *unknown_name = "SMBunknown";
1717 if (smb_messages[type].name == NULL)
1718 return(unknown_name);
1720 return(smb_messages[type].name);
1723 /****************************************************************************
1724 Helper functions for contruct_reply.
1725 ****************************************************************************/
1727 void add_to_common_flags2(uint32 v)
1729 common_flags2 |= v;
1732 void remove_from_common_flags2(uint32 v)
1734 common_flags2 &= ~v;
1737 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1738 char *outbuf)
1740 srv_set_message(outbuf,0,0,false);
1742 SCVAL(outbuf, smb_com, req->cmd);
1743 SIVAL(outbuf,smb_rcls,0);
1744 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1745 SSVAL(outbuf,smb_flg2,
1746 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1747 common_flags2);
1748 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1750 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1751 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1752 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1753 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1756 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1758 construct_reply_common(req, (char *)req->inbuf, outbuf);
1762 * How many bytes have we already accumulated up to the current wct field
1763 * offset?
1766 size_t req_wct_ofs(struct smb_request *req)
1768 size_t buf_size;
1770 if (req->chain_outbuf == NULL) {
1771 return smb_wct - 4;
1773 buf_size = talloc_get_size(req->chain_outbuf);
1774 if ((buf_size % 4) != 0) {
1775 buf_size += (4 - (buf_size % 4));
1777 return buf_size - 4;
1781 * Hack around reply_nterror & friends not being aware of chained requests,
1782 * generating illegal (i.e. wct==0) chain replies.
1785 static void fixup_chain_error_packet(struct smb_request *req)
1787 uint8_t *outbuf = req->outbuf;
1788 req->outbuf = NULL;
1789 reply_outbuf(req, 2, 0);
1790 memcpy(req->outbuf, outbuf, smb_wct);
1791 TALLOC_FREE(outbuf);
1792 SCVAL(req->outbuf, smb_vwv0, 0xff);
1796 * @brief Find the smb_cmd offset of the last command pushed
1797 * @param[in] buf The buffer we're building up
1798 * @retval Where can we put our next andx cmd?
1800 * While chaining requests, the "next" request we're looking at needs to put
1801 * its SMB_Command before the data the previous request already built up added
1802 * to the chain. Find the offset to the place where we have to put our cmd.
1805 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1807 uint8_t cmd;
1808 size_t ofs;
1810 cmd = CVAL(buf, smb_com);
1812 SMB_ASSERT(is_andx_req(cmd));
1814 ofs = smb_vwv0;
1816 while (CVAL(buf, ofs) != 0xff) {
1818 if (!is_andx_req(CVAL(buf, ofs))) {
1819 return false;
1823 * ofs is from start of smb header, so add the 4 length
1824 * bytes. The next cmd is right after the wct field.
1826 ofs = SVAL(buf, ofs+2) + 4 + 1;
1828 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1831 *pofs = ofs;
1832 return true;
1836 * @brief Do the smb chaining at a buffer level
1837 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1838 * @param[in] smb_command The command that we want to issue
1839 * @param[in] wct How many words?
1840 * @param[in] vwv The words, already in network order
1841 * @param[in] bytes_alignment How shall we align "bytes"?
1842 * @param[in] num_bytes How many bytes?
1843 * @param[in] bytes The data the request ships
1845 * smb_splice_chain() adds the vwv and bytes to the request already present in
1846 * *poutbuf.
1849 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1850 uint8_t wct, const uint16_t *vwv,
1851 size_t bytes_alignment,
1852 uint32_t num_bytes, const uint8_t *bytes)
1854 uint8_t *outbuf;
1855 size_t old_size, new_size;
1856 size_t ofs;
1857 size_t chain_padding = 0;
1858 size_t bytes_padding = 0;
1859 bool first_request;
1861 old_size = talloc_get_size(*poutbuf);
1864 * old_size == smb_wct means we're pushing the first request in for
1865 * libsmb/
1868 first_request = (old_size == smb_wct);
1870 if (!first_request && ((old_size % 4) != 0)) {
1872 * Align the wct field of subsequent requests to a 4-byte
1873 * boundary
1875 chain_padding = 4 - (old_size % 4);
1879 * After the old request comes the new wct field (1 byte), the vwv's
1880 * and the num_bytes field. After at we might need to align the bytes
1881 * given to us to "bytes_alignment", increasing the num_bytes value.
1884 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1886 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1887 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1890 new_size += bytes_padding + num_bytes;
1892 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1893 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1894 (unsigned)new_size));
1895 return false;
1898 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1899 if (outbuf == NULL) {
1900 DEBUG(0, ("talloc failed\n"));
1901 return false;
1903 *poutbuf = outbuf;
1905 if (first_request) {
1906 SCVAL(outbuf, smb_com, smb_command);
1907 } else {
1908 size_t andx_cmd_ofs;
1910 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1911 DEBUG(1, ("invalid command chain\n"));
1912 *poutbuf = TALLOC_REALLOC_ARRAY(
1913 NULL, *poutbuf, uint8_t, old_size);
1914 return false;
1917 if (chain_padding != 0) {
1918 memset(outbuf + old_size, 0, chain_padding);
1919 old_size += chain_padding;
1922 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1923 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1926 ofs = old_size;
1929 * Push the chained request:
1931 * wct field
1934 SCVAL(outbuf, ofs, wct);
1935 ofs += 1;
1938 * vwv array
1941 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1942 ofs += sizeof(uint16_t) * wct;
1945 * bcc (byte count)
1948 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1949 ofs += sizeof(uint16_t);
1952 * padding
1955 if (bytes_padding != 0) {
1956 memset(outbuf + ofs, 0, bytes_padding);
1957 ofs += bytes_padding;
1961 * The bytes field
1964 memcpy(outbuf + ofs, bytes, num_bytes);
1966 return true;
1969 /****************************************************************************
1970 Construct a chained reply and add it to the already made reply
1971 ****************************************************************************/
1973 void chain_reply(struct smb_request *req)
1975 size_t smblen = smb_len(req->inbuf);
1976 size_t already_used, length_needed;
1977 uint8_t chain_cmd;
1978 uint32_t chain_offset; /* uint32_t to avoid overflow */
1980 uint8_t wct;
1981 uint16_t *vwv;
1982 uint16_t buflen;
1983 uint8_t *buf;
1985 if (IVAL(req->outbuf, smb_rcls) != 0) {
1986 fixup_chain_error_packet(req);
1990 * Any of the AndX requests and replies have at least a wct of
1991 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1992 * beginning of the SMB header to the next wct field.
1994 * None of the AndX requests put anything valuable in vwv[0] and [1],
1995 * so we can overwrite it here to form the chain.
1998 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1999 if (req->chain_outbuf == NULL) {
2000 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2001 req, req->outbuf, uint8_t,
2002 smb_len(req->outbuf) + 4);
2003 if (req->chain_outbuf == NULL) {
2004 smb_panic("talloc failed");
2007 req->outbuf = NULL;
2008 goto error;
2012 * Here we assume that this is the end of the chain. For that we need
2013 * to set "next command" to 0xff and the offset to 0. If we later find
2014 * more commands in the chain, this will be overwritten again.
2017 SCVAL(req->outbuf, smb_vwv0, 0xff);
2018 SCVAL(req->outbuf, smb_vwv0+1, 0);
2019 SSVAL(req->outbuf, smb_vwv1, 0);
2021 if (req->chain_outbuf == NULL) {
2023 * In req->chain_outbuf we collect all the replies. Start the
2024 * chain by copying in the first reply.
2026 * We do the realloc because later on we depend on
2027 * talloc_get_size to determine the length of
2028 * chain_outbuf. The reply_xxx routines might have
2029 * over-allocated (reply_pipe_read_and_X used to be such an
2030 * example).
2032 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2033 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2034 if (req->chain_outbuf == NULL) {
2035 smb_panic("talloc failed");
2037 req->outbuf = NULL;
2038 } else {
2040 * Update smb headers where subsequent chained commands
2041 * may have updated them.
2043 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2044 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2046 if (!smb_splice_chain(&req->chain_outbuf,
2047 CVAL(req->outbuf, smb_com),
2048 CVAL(req->outbuf, smb_wct),
2049 (uint16_t *)(req->outbuf + smb_vwv),
2050 0, smb_buflen(req->outbuf),
2051 (uint8_t *)smb_buf(req->outbuf))) {
2052 goto error;
2054 TALLOC_FREE(req->outbuf);
2058 * We use the old request's vwv field to grab the next chained command
2059 * and offset into the chained fields.
2062 chain_cmd = CVAL(req->vwv+0, 0);
2063 chain_offset = SVAL(req->vwv+1, 0);
2065 if (chain_cmd == 0xff) {
2067 * End of chain, no more requests from the client. So ship the
2068 * replies.
2070 smb_setlen((char *)(req->chain_outbuf),
2071 talloc_get_size(req->chain_outbuf) - 4);
2073 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2074 true, req->seqnum+1,
2075 IS_CONN_ENCRYPTED(req->conn)
2076 ||req->encrypted,
2077 &req->pcd)) {
2078 exit_server_cleanly("chain_reply: srv_send_smb "
2079 "failed.");
2081 TALLOC_FREE(req->chain_outbuf);
2082 req->done = true;
2083 return;
2086 /* add a new perfcounter for this element of chain */
2087 SMB_PERFCOUNT_ADD(&req->pcd);
2088 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2089 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2092 * Check if the client tries to fool us. The chain offset
2093 * needs to point beyond the current request in the chain, it
2094 * needs to strictly grow. Otherwise we might be tricked into
2095 * an endless loop always processing the same request over and
2096 * over again. We used to assume that vwv and the byte buffer
2097 * array in a chain are always attached, but OS/2 the
2098 * Write&X/Read&X chain puts the Read&X vwv array right behind
2099 * the Write&X vwv chain. The Write&X bcc array is put behind
2100 * the Read&X vwv array. So now we check whether the chain
2101 * offset points strictly behind the previous vwv
2102 * array. req->buf points right after the vwv array of the
2103 * previous request. See
2104 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2105 * information.
2108 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2109 if (chain_offset <= already_used) {
2110 goto error;
2114 * Next check: Make sure the chain offset does not point beyond the
2115 * overall smb request length.
2118 length_needed = chain_offset+1; /* wct */
2119 if (length_needed > smblen) {
2120 goto error;
2124 * Now comes the pointer magic. Goal here is to set up req->vwv and
2125 * req->buf correctly again to be able to call the subsequent
2126 * switch_message(). The chain offset (the former vwv[1]) points at
2127 * the new wct field.
2130 wct = CVAL(smb_base(req->inbuf), chain_offset);
2133 * Next consistency check: Make the new vwv array fits in the overall
2134 * smb request.
2137 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2138 if (length_needed > smblen) {
2139 goto error;
2141 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2144 * Now grab the new byte buffer....
2147 buflen = SVAL(vwv+wct, 0);
2150 * .. and check that it fits.
2153 length_needed += buflen;
2154 if (length_needed > smblen) {
2155 goto error;
2157 buf = (uint8_t *)(vwv+wct+1);
2159 req->cmd = chain_cmd;
2160 req->wct = wct;
2161 req->vwv = vwv;
2162 req->buflen = buflen;
2163 req->buf = buf;
2165 switch_message(chain_cmd, req, smblen);
2167 if (req->outbuf == NULL) {
2169 * This happens if the chained command has suspended itself or
2170 * if it has called srv_send_smb() itself.
2172 return;
2176 * We end up here if the chained command was not itself chained or
2177 * suspended, but for example a close() command. We now need to splice
2178 * the chained commands' outbuf into the already built up chain_outbuf
2179 * and ship the result.
2181 goto done;
2183 error:
2185 * We end up here if there's any error in the chain syntax. Report a
2186 * DOS error, just like Windows does.
2188 reply_force_doserror(req, ERRSRV, ERRerror);
2189 fixup_chain_error_packet(req);
2191 done:
2193 * This scary statement intends to set the
2194 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2195 * to the value req->outbuf carries
2197 SSVAL(req->chain_outbuf, smb_flg2,
2198 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2199 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2202 * Transfer the error codes from the subrequest to the main one
2204 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2205 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2207 if (!smb_splice_chain(&req->chain_outbuf,
2208 CVAL(req->outbuf, smb_com),
2209 CVAL(req->outbuf, smb_wct),
2210 (uint16_t *)(req->outbuf + smb_vwv),
2211 0, smb_buflen(req->outbuf),
2212 (uint8_t *)smb_buf(req->outbuf))) {
2213 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2215 TALLOC_FREE(req->outbuf);
2217 smb_setlen((char *)(req->chain_outbuf),
2218 talloc_get_size(req->chain_outbuf) - 4);
2220 show_msg((char *)(req->chain_outbuf));
2222 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2223 true, req->seqnum+1,
2224 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2225 &req->pcd)) {
2226 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2228 TALLOC_FREE(req->chain_outbuf);
2229 req->done = true;
2232 /****************************************************************************
2233 Check if services need reloading.
2234 ****************************************************************************/
2236 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2239 if (last_smb_conf_reload_time == 0) {
2240 last_smb_conf_reload_time = t;
2243 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2244 reload_services(sconn->msg_ctx, sconn->sock, True);
2245 last_smb_conf_reload_time = t;
2249 static bool fd_is_readable(int fd)
2251 int ret, revents;
2253 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2255 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2259 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2261 /* TODO: make write nonblocking */
2264 static void smbd_server_connection_read_handler(
2265 struct smbd_server_connection *conn, int fd)
2267 uint8_t *inbuf = NULL;
2268 size_t inbuf_len = 0;
2269 size_t unread_bytes = 0;
2270 bool encrypted = false;
2271 TALLOC_CTX *mem_ctx = talloc_tos();
2272 NTSTATUS status;
2273 uint32_t seqnum;
2275 bool from_client = (conn->sock == fd);
2277 if (from_client) {
2278 smbd_lock_socket(conn);
2280 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2281 DEBUG(10,("the echo listener was faster\n"));
2282 smbd_unlock_socket(conn);
2283 return;
2286 /* TODO: make this completely nonblocking */
2287 status = receive_smb_talloc(mem_ctx, conn, fd,
2288 (char **)(void *)&inbuf,
2289 0, /* timeout */
2290 &unread_bytes,
2291 &encrypted,
2292 &inbuf_len, &seqnum,
2293 false /* trusted channel */);
2294 smbd_unlock_socket(conn);
2295 } else {
2296 /* TODO: make this completely nonblocking */
2297 status = receive_smb_talloc(mem_ctx, conn, fd,
2298 (char **)(void *)&inbuf,
2299 0, /* timeout */
2300 &unread_bytes,
2301 &encrypted,
2302 &inbuf_len, &seqnum,
2303 true /* trusted channel */);
2306 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2307 goto process;
2309 if (NT_STATUS_IS_ERR(status)) {
2310 exit_server_cleanly("failed to receive smb request");
2312 if (!NT_STATUS_IS_OK(status)) {
2313 return;
2316 process:
2317 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2318 seqnum, encrypted, NULL);
2321 static void smbd_server_connection_handler(struct event_context *ev,
2322 struct fd_event *fde,
2323 uint16_t flags,
2324 void *private_data)
2326 struct smbd_server_connection *conn = talloc_get_type(private_data,
2327 struct smbd_server_connection);
2329 if (flags & EVENT_FD_WRITE) {
2330 smbd_server_connection_write_handler(conn);
2331 return;
2333 if (flags & EVENT_FD_READ) {
2334 smbd_server_connection_read_handler(conn, conn->sock);
2335 return;
2339 static void smbd_server_echo_handler(struct event_context *ev,
2340 struct fd_event *fde,
2341 uint16_t flags,
2342 void *private_data)
2344 struct smbd_server_connection *conn = talloc_get_type(private_data,
2345 struct smbd_server_connection);
2347 if (flags & EVENT_FD_WRITE) {
2348 smbd_server_connection_write_handler(conn);
2349 return;
2351 if (flags & EVENT_FD_READ) {
2352 smbd_server_connection_read_handler(
2353 conn, conn->smb1.echo_handler.trusted_fd);
2354 return;
2358 /****************************************************************************
2359 received when we should release a specific IP
2360 ****************************************************************************/
2361 static void release_ip(const char *ip, void *priv)
2363 const char *addr = (const char *)priv;
2364 const char *p = addr;
2366 if (strncmp("::ffff:", addr, 7) == 0) {
2367 p = addr + 7;
2370 DEBUG(10, ("Got release IP message for %s, "
2371 "our address is %s\n", ip, p));
2373 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2374 /* we can't afford to do a clean exit - that involves
2375 database writes, which would potentially mean we
2376 are still running after the failover has finished -
2377 we have to get rid of this process ID straight
2378 away */
2379 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2380 ip));
2381 /* note we must exit with non-zero status so the unclean handler gets
2382 called in the parent, so that the brl database is tickled */
2383 _exit(1);
2387 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2388 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2390 struct smbd_server_connection *sconn = talloc_get_type_abort(
2391 private_data, struct smbd_server_connection);
2393 release_ip((char *)data->data, sconn->client_id.addr);
2396 #ifdef CLUSTER_SUPPORT
2397 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2398 struct sockaddr_storage *client)
2400 socklen_t length;
2401 length = sizeof(*server);
2402 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2403 return -1;
2405 length = sizeof(*client);
2406 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2407 return -1;
2409 return 0;
2411 #endif
2414 * Send keepalive packets to our client
2416 static bool keepalive_fn(const struct timeval *now, void *private_data)
2418 struct smbd_server_connection *sconn = smbd_server_conn;
2419 bool ret;
2421 if (sconn->using_smb2) {
2422 /* Don't do keepalives on an SMB2 connection. */
2423 return false;
2426 smbd_lock_socket(smbd_server_conn);
2427 ret = send_keepalive(sconn->sock);
2428 smbd_unlock_socket(smbd_server_conn);
2430 if (!ret) {
2431 char addr[INET6_ADDRSTRLEN];
2433 * Try and give an error message saying what
2434 * client failed.
2436 DEBUG(0, ("send_keepalive failed for client %s. "
2437 "Error %s - exiting\n",
2438 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2439 strerror(errno)));
2440 return False;
2442 return True;
2446 * Do the recurring check if we're idle
2448 static bool deadtime_fn(const struct timeval *now, void *private_data)
2450 struct smbd_server_connection *sconn =
2451 (struct smbd_server_connection *)private_data;
2453 if ((conn_num_open(sconn) == 0)
2454 || (conn_idle_all(sconn, now->tv_sec))) {
2455 DEBUG( 2, ( "Closing idle connection\n" ) );
2456 messaging_send(sconn->msg_ctx,
2457 messaging_server_id(sconn->msg_ctx),
2458 MSG_SHUTDOWN, &data_blob_null);
2459 return False;
2462 return True;
2466 * Do the recurring log file and smb.conf reload checks.
2469 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2471 struct smbd_server_connection *sconn = talloc_get_type_abort(
2472 private_data, struct smbd_server_connection);
2474 DEBUG(5, ("housekeeping\n"));
2476 change_to_root_user();
2478 /* update printer queue caches if necessary */
2479 update_monitored_printq_cache(sconn->msg_ctx);
2481 /* check if we need to reload services */
2482 check_reload(sconn, time_mono(NULL));
2484 /* Change machine password if neccessary. */
2485 attempt_machine_password_change();
2488 * Force a log file check.
2490 force_check_log_size();
2491 check_log_size();
2492 return true;
2495 static int create_unlink_tmp(const char *dir)
2497 char *fname;
2498 int fd;
2500 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2501 if (fname == NULL) {
2502 errno = ENOMEM;
2503 return -1;
2505 fd = mkstemp(fname);
2506 if (fd == -1) {
2507 TALLOC_FREE(fname);
2508 return -1;
2510 if (unlink(fname) == -1) {
2511 int sys_errno = errno;
2512 close(fd);
2513 TALLOC_FREE(fname);
2514 errno = sys_errno;
2515 return -1;
2517 TALLOC_FREE(fname);
2518 return fd;
2521 struct smbd_echo_state {
2522 struct tevent_context *ev;
2523 struct iovec *pending;
2524 struct smbd_server_connection *sconn;
2525 int parent_pipe;
2527 struct tevent_fd *parent_fde;
2529 struct tevent_fd *read_fde;
2530 struct tevent_req *write_req;
2533 static void smbd_echo_writer_done(struct tevent_req *req);
2535 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2537 int num_pending;
2539 if (state->write_req != NULL) {
2540 return;
2543 num_pending = talloc_array_length(state->pending);
2544 if (num_pending == 0) {
2545 return;
2548 state->write_req = writev_send(state, state->ev, NULL,
2549 state->parent_pipe, false,
2550 state->pending, num_pending);
2551 if (state->write_req == NULL) {
2552 DEBUG(1, ("writev_send failed\n"));
2553 exit(1);
2556 talloc_steal(state->write_req, state->pending);
2557 state->pending = NULL;
2559 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2560 state);
2563 static void smbd_echo_writer_done(struct tevent_req *req)
2565 struct smbd_echo_state *state = tevent_req_callback_data(
2566 req, struct smbd_echo_state);
2567 ssize_t written;
2568 int err;
2570 written = writev_recv(req, &err);
2571 TALLOC_FREE(req);
2572 state->write_req = NULL;
2573 if (written == -1) {
2574 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2575 exit(1);
2577 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2578 smbd_echo_activate_writer(state);
2581 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2582 uint32_t seqnum)
2584 struct smb_request req;
2585 uint16_t num_replies;
2586 size_t out_len;
2587 char *outbuf;
2588 bool ok;
2590 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2591 DEBUG(10, ("Got netbios keepalive\n"));
2593 * Just swallow it
2595 return true;
2598 if (inbuf_len < smb_size) {
2599 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2600 return false;
2602 if (!valid_smb_header(inbuf)) {
2603 DEBUG(10, ("Got invalid SMB header\n"));
2604 return false;
2607 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2608 seqnum)) {
2609 return false;
2611 req.inbuf = inbuf;
2613 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2614 smb_messages[req.cmd].name
2615 ? smb_messages[req.cmd].name : "unknown"));
2617 if (req.cmd != SMBecho) {
2618 return false;
2620 if (req.wct < 1) {
2621 return false;
2624 num_replies = SVAL(req.vwv+0, 0);
2625 if (num_replies != 1) {
2626 /* Not a Windows "Hey, you're still there?" request */
2627 return false;
2630 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2631 1, req.buflen)) {
2632 DEBUG(10, ("create_outbuf failed\n"));
2633 return false;
2635 req.outbuf = (uint8_t *)outbuf;
2637 SSVAL(req.outbuf, smb_vwv0, num_replies);
2639 if (req.buflen > 0) {
2640 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2643 out_len = smb_len(req.outbuf) + 4;
2645 ok = srv_send_smb(req.sconn,
2646 (char *)outbuf,
2647 true, seqnum+1,
2648 false, &req.pcd);
2649 TALLOC_FREE(outbuf);
2650 if (!ok) {
2651 exit(1);
2654 return true;
2657 static void smbd_echo_exit(struct tevent_context *ev,
2658 struct tevent_fd *fde, uint16_t flags,
2659 void *private_data)
2661 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2662 exit(0);
2665 static void smbd_echo_reader(struct tevent_context *ev,
2666 struct tevent_fd *fde, uint16_t flags,
2667 void *private_data)
2669 struct smbd_echo_state *state = talloc_get_type_abort(
2670 private_data, struct smbd_echo_state);
2671 struct smbd_server_connection *sconn = state->sconn;
2672 size_t unread, num_pending;
2673 NTSTATUS status;
2674 struct iovec *tmp;
2675 size_t iov_len;
2676 uint32_t seqnum = 0;
2677 bool reply;
2678 bool ok;
2679 bool encrypted = false;
2681 smb_msleep(1000);
2683 ok = smbd_lock_socket_internal(sconn);
2684 if (!ok) {
2685 DEBUG(0, ("%s: failed to lock socket\n",
2686 __location__));
2687 exit(1);
2690 if (!fd_is_readable(sconn->sock)) {
2691 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2692 (int)sys_getpid()));
2693 ok = smbd_unlock_socket_internal(sconn);
2694 if (!ok) {
2695 DEBUG(1, ("%s: failed to unlock socket in\n",
2696 __location__));
2697 exit(1);
2699 return;
2702 num_pending = talloc_array_length(state->pending);
2703 tmp = talloc_realloc(state, state->pending, struct iovec,
2704 num_pending+1);
2705 if (tmp == NULL) {
2706 DEBUG(1, ("talloc_realloc failed\n"));
2707 exit(1);
2709 state->pending = tmp;
2711 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2713 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2714 (char **)(void *)&state->pending[num_pending].iov_base,
2715 0 /* timeout */,
2716 &unread,
2717 &encrypted,
2718 &iov_len,
2719 &seqnum,
2720 false /* trusted_channel*/);
2721 if (!NT_STATUS_IS_OK(status)) {
2722 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2723 (int)sys_getpid(), nt_errstr(status)));
2724 exit(1);
2726 state->pending[num_pending].iov_len = iov_len;
2728 ok = smbd_unlock_socket_internal(sconn);
2729 if (!ok) {
2730 DEBUG(1, ("%s: failed to unlock socket in\n",
2731 __location__));
2732 exit(1);
2735 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2736 state->pending[num_pending].iov_len,
2737 seqnum);
2738 if (reply) {
2739 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2740 /* no check, shrinking by some bytes does not fail */
2741 state->pending = talloc_realloc(state, state->pending,
2742 struct iovec,
2743 num_pending);
2744 return;
2747 if (state->pending[num_pending].iov_len >= smb_size) {
2749 * place the seqnum in the packet so that the main process
2750 * can reply with signing
2752 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2753 smb_ss_field, seqnum);
2754 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2755 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2758 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2759 smbd_echo_activate_writer(state);
2762 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2763 int parent_pipe)
2765 struct smbd_echo_state *state;
2767 state = talloc_zero(sconn, struct smbd_echo_state);
2768 if (state == NULL) {
2769 DEBUG(1, ("talloc failed\n"));
2770 return;
2772 state->sconn = sconn;
2773 state->parent_pipe = parent_pipe;
2774 state->ev = s3_tevent_context_init(state);
2775 if (state->ev == NULL) {
2776 DEBUG(1, ("tevent_context_init failed\n"));
2777 TALLOC_FREE(state);
2778 return;
2780 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2781 TEVENT_FD_READ, smbd_echo_exit,
2782 state);
2783 if (state->parent_fde == NULL) {
2784 DEBUG(1, ("tevent_add_fd failed\n"));
2785 TALLOC_FREE(state);
2786 return;
2788 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2789 TEVENT_FD_READ, smbd_echo_reader,
2790 state);
2791 if (state->read_fde == NULL) {
2792 DEBUG(1, ("tevent_add_fd failed\n"));
2793 TALLOC_FREE(state);
2794 return;
2797 while (true) {
2798 if (tevent_loop_once(state->ev) == -1) {
2799 DEBUG(1, ("tevent_loop_once failed: %s\n",
2800 strerror(errno)));
2801 break;
2804 TALLOC_FREE(state);
2808 * Handle SMBecho requests in a forked child process
2810 bool fork_echo_handler(struct smbd_server_connection *sconn)
2812 int listener_pipe[2];
2813 int res;
2814 pid_t child;
2816 res = pipe(listener_pipe);
2817 if (res == -1) {
2818 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2819 return false;
2821 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2822 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2823 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2824 goto fail;
2827 child = sys_fork();
2828 if (child == 0) {
2829 NTSTATUS status;
2831 close(listener_pipe[0]);
2832 set_blocking(listener_pipe[1], false);
2834 status = reinit_after_fork(sconn->msg_ctx,
2835 smbd_event_context(),
2836 procid_self(), false);
2837 if (!NT_STATUS_IS_OK(status)) {
2838 DEBUG(1, ("reinit_after_fork failed: %s\n",
2839 nt_errstr(status)));
2840 exit(1);
2842 smbd_echo_loop(sconn, listener_pipe[1]);
2843 exit(0);
2845 close(listener_pipe[1]);
2846 listener_pipe[1] = -1;
2847 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2849 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2852 * Without smb signing this is the same as the normal smbd
2853 * listener. This needs to change once signing comes in.
2855 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2856 sconn,
2857 sconn->smb1.echo_handler.trusted_fd,
2858 EVENT_FD_READ,
2859 smbd_server_echo_handler,
2860 sconn);
2861 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2862 DEBUG(1, ("event_add_fd failed\n"));
2863 goto fail;
2866 return true;
2868 fail:
2869 if (listener_pipe[0] != -1) {
2870 close(listener_pipe[0]);
2872 if (listener_pipe[1] != -1) {
2873 close(listener_pipe[1]);
2875 sconn->smb1.echo_handler.trusted_fd = -1;
2876 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2877 close(sconn->smb1.echo_handler.socket_lock_fd);
2879 sconn->smb1.echo_handler.trusted_fd = -1;
2880 sconn->smb1.echo_handler.socket_lock_fd = -1;
2881 return false;
2884 #if CLUSTER_SUPPORT
2886 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2887 struct sockaddr_storage *srv,
2888 struct sockaddr_storage *clnt)
2890 struct ctdbd_connection *cconn;
2891 char tmp_addr[INET6_ADDRSTRLEN];
2892 char *addr;
2894 cconn = messaging_ctdbd_connection();
2895 if (cconn == NULL) {
2896 return NT_STATUS_NO_MEMORY;
2899 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2900 addr = talloc_strdup(cconn, tmp_addr);
2901 if (addr == NULL) {
2902 return NT_STATUS_NO_MEMORY;
2904 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2907 #endif
2909 /****************************************************************************
2910 Process commands from the client
2911 ****************************************************************************/
2913 void smbd_process(struct smbd_server_connection *sconn)
2915 TALLOC_CTX *frame = talloc_stackframe();
2916 struct sockaddr_storage ss;
2917 struct sockaddr *sa = NULL;
2918 socklen_t sa_socklen;
2919 struct tsocket_address *local_address = NULL;
2920 struct tsocket_address *remote_address = NULL;
2921 const char *remaddr = NULL;
2922 int ret;
2924 if (lp_maxprotocol() == PROTOCOL_SMB2) {
2926 * We're not making the decision here,
2927 * we're just allowing the client
2928 * to decide between SMB1 and SMB2
2929 * with the first negprot
2930 * packet.
2932 sconn->using_smb2 = true;
2935 /* Ensure child is set to blocking mode */
2936 set_blocking(sconn->sock,True);
2938 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2939 set_socket_options(sconn->sock, lp_socket_options());
2941 sa = (struct sockaddr *)(void *)&ss;
2942 sa_socklen = sizeof(ss);
2943 ret = getpeername(sconn->sock, sa, &sa_socklen);
2944 if (ret != 0) {
2945 int level = (errno == ENOTCONN)?2:0;
2946 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2947 exit_server_cleanly("getpeername() failed.\n");
2949 ret = tsocket_address_bsd_from_sockaddr(sconn,
2950 sa, sa_socklen,
2951 &remote_address);
2952 if (ret != 0) {
2953 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2954 __location__, strerror(errno)));
2955 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2958 sa = (struct sockaddr *)(void *)&ss;
2959 sa_socklen = sizeof(ss);
2960 ret = getsockname(sconn->sock, sa, &sa_socklen);
2961 if (ret != 0) {
2962 int level = (errno == ENOTCONN)?2:0;
2963 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2964 exit_server_cleanly("getsockname() failed.\n");
2966 ret = tsocket_address_bsd_from_sockaddr(sconn,
2967 sa, sa_socklen,
2968 &local_address);
2969 if (ret != 0) {
2970 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2971 __location__, strerror(errno)));
2972 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2975 sconn->local_address = local_address;
2976 sconn->remote_address = remote_address;
2978 if (tsocket_address_is_inet(remote_address, "ip")) {
2979 remaddr = tsocket_address_inet_addr_string(
2980 sconn->remote_address,
2981 talloc_tos());
2982 if (remaddr == NULL) {
2985 } else {
2986 remaddr = "0.0.0.0";
2989 /* this is needed so that we get decent entries
2990 in smbstatus for port 445 connects */
2991 set_remote_machine_name(remaddr, false);
2992 reload_services(sconn->msg_ctx, sconn->sock, true);
2995 * Before the first packet, check the global hosts allow/ hosts deny
2996 * parameters before doing any parsing of packets passed to us by the
2997 * client. This prevents attacks on our parsing code from hosts not in
2998 * the hosts allow list.
3001 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3002 sconn->client_id.name,
3003 sconn->client_id.addr)) {
3005 * send a negative session response "not listening on calling
3006 * name"
3008 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3009 DEBUG( 1, ("Connection denied from %s to %s\n",
3010 tsocket_address_string(remote_address, talloc_tos()),
3011 tsocket_address_string(local_address, talloc_tos())));
3012 (void)srv_send_smb(sconn,(char *)buf, false,
3013 0, false, NULL);
3014 exit_server_cleanly("connection denied");
3017 DEBUG(10, ("Connection allowed from %s to %s\n",
3018 tsocket_address_string(remote_address, talloc_tos()),
3019 tsocket_address_string(local_address, talloc_tos())));
3021 init_modules();
3023 smb_perfcount_init();
3025 if (!init_account_policy()) {
3026 exit_server("Could not open account policy tdb.\n");
3029 if (*lp_rootdir()) {
3030 if (chroot(lp_rootdir()) != 0) {
3031 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3032 exit_server("Failed to chroot()");
3034 if (chdir("/") == -1) {
3035 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3036 exit_server("Failed to chroot()");
3038 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3041 if (!srv_init_signing(sconn)) {
3042 exit_server("Failed to init smb_signing");
3045 /* Setup oplocks */
3046 if (!init_oplocks(sconn->msg_ctx))
3047 exit_server("Failed to init oplocks");
3049 /* register our message handlers */
3050 messaging_register(sconn->msg_ctx, NULL,
3051 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3052 messaging_register(sconn->msg_ctx, sconn,
3053 MSG_SMB_RELEASE_IP, msg_release_ip);
3054 messaging_register(sconn->msg_ctx, NULL,
3055 MSG_SMB_CLOSE_FILE, msg_close_file);
3058 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3059 * MSGs to all child processes
3061 messaging_deregister(sconn->msg_ctx,
3062 MSG_DEBUG, NULL);
3063 messaging_register(sconn->msg_ctx, NULL,
3064 MSG_DEBUG, debug_message);
3066 if ((lp_keepalive() != 0)
3067 && !(event_add_idle(smbd_event_context(), NULL,
3068 timeval_set(lp_keepalive(), 0),
3069 "keepalive", keepalive_fn,
3070 NULL))) {
3071 DEBUG(0, ("Could not add keepalive event\n"));
3072 exit(1);
3075 if (!(event_add_idle(smbd_event_context(), NULL,
3076 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3077 "deadtime", deadtime_fn, sconn))) {
3078 DEBUG(0, ("Could not add deadtime event\n"));
3079 exit(1);
3082 if (!(event_add_idle(smbd_event_context(), NULL,
3083 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3084 "housekeeping", housekeeping_fn, sconn))) {
3085 DEBUG(0, ("Could not add housekeeping event\n"));
3086 exit(1);
3089 #ifdef CLUSTER_SUPPORT
3091 if (lp_clustering()) {
3093 * We need to tell ctdb about our client's TCP
3094 * connection, so that for failover ctdbd can send
3095 * tickle acks, triggering a reconnection by the
3096 * client.
3099 struct sockaddr_storage srv, clnt;
3101 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3102 NTSTATUS status;
3103 status = smbd_register_ips(sconn, &srv, &clnt);
3104 if (!NT_STATUS_IS_OK(status)) {
3105 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3106 nt_errstr(status)));
3108 } else
3110 DEBUG(0,("Unable to get tcp info for "
3111 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3112 strerror(errno)));
3116 #endif
3118 sconn->nbt.got_session = false;
3120 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3122 sconn->smb1.sessions.done_sesssetup = false;
3123 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3124 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3125 /* users from session setup */
3126 sconn->smb1.sessions.session_userlist = NULL;
3127 /* workgroup from session setup. */
3128 sconn->smb1.sessions.session_workgroup = NULL;
3129 /* this holds info on user ids that are already validated for this VC */
3130 sconn->smb1.sessions.validated_users = NULL;
3131 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3132 sconn->smb1.sessions.num_validated_vuids = 0;
3134 conn_init(sconn);
3135 if (!init_dptrs(sconn)) {
3136 exit_server("init_dptrs() failed");
3139 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3140 sconn,
3141 sconn->sock,
3142 EVENT_FD_READ,
3143 smbd_server_connection_handler,
3144 sconn);
3145 if (!sconn->smb1.fde) {
3146 exit_server("failed to create smbd_server_connection fde");
3149 TALLOC_FREE(frame);
3151 while (True) {
3152 NTSTATUS status;
3154 frame = talloc_stackframe_pool(8192);
3156 errno = 0;
3158 status = smbd_server_connection_loop_once(sconn);
3159 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3160 !NT_STATUS_IS_OK(status)) {
3161 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3162 " exiting\n", nt_errstr(status)));
3163 break;
3166 TALLOC_FREE(frame);
3169 exit_server_cleanly(NULL);
3172 bool req_is_in_chain(struct smb_request *req)
3174 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3176 * We're right now handling a subsequent request, so we must
3177 * be in a chain
3179 return true;
3182 if (!is_andx_req(req->cmd)) {
3183 return false;
3186 if (req->wct < 2) {
3188 * Okay, an illegal request, but definitely not chained :-)
3190 return false;
3193 return (CVAL(req->vwv+0, 0) != 0xFF);