s3:smbd: use PROTOCOL_SMB2_02 instead PROTOCOL_SMB2
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blobd3957fe936a5416868e4995cf74f48e2a37c48fa
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",
291 tsocket_address_string(sconn->remote_address,
292 talloc_tos()),
293 nt_errstr(status)));
294 return status;
298 * Ok - now try and see if this is a possible
299 * valid writeX call.
302 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
304 * If the data offset is beyond what
305 * we've read, drain the extra bytes.
307 uint16_t doff = SVAL(writeX_header,smb_vwv11);
308 ssize_t newlen;
310 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
311 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
312 if (drain_socket(sock, drain) != drain) {
313 smb_panic("receive_smb_raw_talloc_partial_read:"
314 " failed to drain pending bytes");
316 } else {
317 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
320 /* Spoof down the length and null out the bcc. */
321 set_message_bcc(writeX_header, 0);
322 newlen = smb_len(writeX_header);
324 /* Copy the header we've written. */
326 *buffer = (char *)talloc_memdup(mem_ctx,
327 writeX_header,
328 sizeof(writeX_header));
330 if (*buffer == NULL) {
331 DEBUG(0, ("Could not allocate inbuf of length %d\n",
332 (int)sizeof(writeX_header)));
333 return NT_STATUS_NO_MEMORY;
336 /* Work out the remaining bytes. */
337 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
338 *len_ret = newlen + 4;
339 return NT_STATUS_OK;
342 if (!valid_packet_size(len)) {
343 return NT_STATUS_INVALID_PARAMETER;
347 * Not a valid writeX call. Just do the standard
348 * talloc and return.
351 *buffer = talloc_array(mem_ctx, char, len+4);
353 if (*buffer == NULL) {
354 DEBUG(0, ("Could not allocate inbuf of length %d\n",
355 (int)len+4));
356 return NT_STATUS_NO_MEMORY;
359 /* Copy in what we already read. */
360 memcpy(*buffer,
361 writeX_header,
362 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
363 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
365 if(toread > 0) {
366 status = read_packet_remainder(
367 sock,
368 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
369 timeout, toread);
371 if (!NT_STATUS_IS_OK(status)) {
372 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
373 nt_errstr(status)));
374 return status;
378 *len_ret = len + 4;
379 return NT_STATUS_OK;
382 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
383 struct smbd_server_connection *sconn,
384 int sock,
385 char **buffer, unsigned int timeout,
386 size_t *p_unread, size_t *plen)
388 char lenbuf[4];
389 size_t len;
390 int min_recv_size = lp_min_receive_file_size();
391 NTSTATUS status;
393 *p_unread = 0;
395 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
396 &len);
397 if (!NT_STATUS_IS_OK(status)) {
398 return status;
401 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
402 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
403 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
404 !srv_is_signing_active(sconn) &&
405 sconn->smb1.echo_handler.trusted_fde == NULL) {
407 return receive_smb_raw_talloc_partial_read(
408 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
409 p_unread, plen);
412 if (!valid_packet_size(len)) {
413 return NT_STATUS_INVALID_PARAMETER;
417 * The +4 here can't wrap, we've checked the length above already.
420 *buffer = talloc_array(mem_ctx, char, len+4);
422 if (*buffer == NULL) {
423 DEBUG(0, ("Could not allocate inbuf of length %d\n",
424 (int)len+4));
425 return NT_STATUS_NO_MEMORY;
428 memcpy(*buffer, lenbuf, sizeof(lenbuf));
430 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
431 if (!NT_STATUS_IS_OK(status)) {
432 return status;
435 *plen = len + 4;
436 return NT_STATUS_OK;
439 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
440 struct smbd_server_connection *sconn,
441 int sock,
442 char **buffer, unsigned int timeout,
443 size_t *p_unread, bool *p_encrypted,
444 size_t *p_len,
445 uint32_t *seqnum,
446 bool trusted_channel)
448 size_t len = 0;
449 NTSTATUS status;
451 *p_encrypted = false;
453 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
454 p_unread, &len);
455 if (!NT_STATUS_IS_OK(status)) {
456 DEBUG(1, ("read_smb_length_return_keepalive failed for "
457 "client %s read error = %s.\n",
458 tsocket_address_string(sconn->remote_address,
459 talloc_tos()),
460 nt_errstr(status)));
461 return status;
464 if (is_encrypted_packet((uint8_t *)*buffer)) {
465 status = srv_decrypt_buffer(*buffer);
466 if (!NT_STATUS_IS_OK(status)) {
467 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
468 "incoming packet! Error %s\n",
469 nt_errstr(status) ));
470 return status;
472 *p_encrypted = true;
475 /* Check the incoming SMB signature. */
476 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
477 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
478 "incoming packet!\n"));
479 return NT_STATUS_INVALID_NETWORK_RESPONSE;
482 *p_len = len;
483 return NT_STATUS_OK;
487 * Initialize a struct smb_request from an inbuf
490 static bool init_smb_request(struct smb_request *req,
491 struct smbd_server_connection *sconn,
492 const uint8 *inbuf,
493 size_t unread_bytes, bool encrypted,
494 uint32_t seqnum)
496 size_t req_size = smb_len(inbuf) + 4;
497 /* Ensure we have at least smb_size bytes. */
498 if (req_size < smb_size) {
499 DEBUG(0,("init_smb_request: invalid request size %u\n",
500 (unsigned int)req_size ));
501 return false;
503 req->cmd = CVAL(inbuf, smb_com);
504 req->flags2 = SVAL(inbuf, smb_flg2);
505 req->smbpid = SVAL(inbuf, smb_pid);
506 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
507 req->seqnum = seqnum;
508 req->vuid = SVAL(inbuf, smb_uid);
509 req->tid = SVAL(inbuf, smb_tid);
510 req->wct = CVAL(inbuf, smb_wct);
511 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
512 req->buflen = smb_buflen(inbuf);
513 req->buf = (const uint8_t *)smb_buf_const(inbuf);
514 req->unread_bytes = unread_bytes;
515 req->encrypted = encrypted;
516 req->sconn = sconn;
517 req->conn = conn_find(sconn,req->tid);
518 req->chain_fsp = NULL;
519 req->chain_outbuf = NULL;
520 req->done = false;
521 req->smb2req = NULL;
522 smb_init_perfcount_data(&req->pcd);
524 /* Ensure we have at least wct words and 2 bytes of bcc. */
525 if (smb_size + req->wct*2 > req_size) {
526 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
527 (unsigned int)req->wct,
528 (unsigned int)req_size));
529 return false;
531 /* Ensure bcc is correct. */
532 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
533 DEBUG(0,("init_smb_request: invalid bcc number %u "
534 "(wct = %u, size %u)\n",
535 (unsigned int)req->buflen,
536 (unsigned int)req->wct,
537 (unsigned int)req_size));
538 return false;
541 req->outbuf = NULL;
542 return true;
545 static void process_smb(struct smbd_server_connection *conn,
546 uint8_t *inbuf, size_t nread, size_t unread_bytes,
547 uint32_t seqnum, bool encrypted,
548 struct smb_perfcount_data *deferred_pcd);
550 static void smbd_deferred_open_timer(struct event_context *ev,
551 struct timed_event *te,
552 struct timeval _tval,
553 void *private_data)
555 struct pending_message_list *msg = talloc_get_type(private_data,
556 struct pending_message_list);
557 TALLOC_CTX *mem_ctx = talloc_tos();
558 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
559 uint8_t *inbuf;
561 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
562 msg->buf.length);
563 if (inbuf == NULL) {
564 exit_server("smbd_deferred_open_timer: talloc failed\n");
565 return;
568 /* We leave this message on the queue so the open code can
569 know this is a retry. */
570 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
571 (unsigned long long)mid ));
573 /* Mark the message as processed so this is not
574 * re-processed in error. */
575 msg->processed = true;
577 process_smb(smbd_server_conn, inbuf,
578 msg->buf.length, 0,
579 msg->seqnum, msg->encrypted, &msg->pcd);
581 /* If it's still there and was processed, remove it. */
582 msg = get_deferred_open_message_smb(mid);
583 if (msg && msg->processed) {
584 remove_deferred_open_message_smb(mid);
588 /****************************************************************************
589 Function to push a message onto the tail of a linked list of smb messages ready
590 for processing.
591 ****************************************************************************/
593 static bool push_queued_message(struct smb_request *req,
594 struct timeval request_time,
595 struct timeval end_time,
596 char *private_data, size_t private_len)
598 int msg_len = smb_len(req->inbuf) + 4;
599 struct pending_message_list *msg;
601 msg = talloc_zero(NULL, struct pending_message_list);
603 if(msg == NULL) {
604 DEBUG(0,("push_message: malloc fail (1)\n"));
605 return False;
608 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
609 if(msg->buf.data == NULL) {
610 DEBUG(0,("push_message: malloc fail (2)\n"));
611 TALLOC_FREE(msg);
612 return False;
615 msg->request_time = request_time;
616 msg->seqnum = req->seqnum;
617 msg->encrypted = req->encrypted;
618 msg->processed = false;
619 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
621 if (private_data) {
622 msg->private_data = data_blob_talloc(msg, private_data,
623 private_len);
624 if (msg->private_data.data == NULL) {
625 DEBUG(0,("push_message: malloc fail (3)\n"));
626 TALLOC_FREE(msg);
627 return False;
631 msg->te = event_add_timed(server_event_context(),
632 msg,
633 end_time,
634 smbd_deferred_open_timer,
635 msg);
636 if (!msg->te) {
637 DEBUG(0,("push_message: event_add_timed failed\n"));
638 TALLOC_FREE(msg);
639 return false;
642 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
644 DEBUG(10,("push_message: pushed message length %u on "
645 "deferred_open_queue\n", (unsigned int)msg_len));
647 return True;
650 /****************************************************************************
651 Function to delete a sharing violation open message by mid.
652 ****************************************************************************/
654 void remove_deferred_open_message_smb(uint64_t mid)
656 struct pending_message_list *pml;
658 if (smbd_server_conn->using_smb2) {
659 remove_deferred_open_message_smb2(smbd_server_conn, mid);
660 return;
663 for (pml = deferred_open_queue; pml; pml = pml->next) {
664 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
665 DEBUG(10,("remove_deferred_open_message_smb: "
666 "deleting mid %llu len %u\n",
667 (unsigned long long)mid,
668 (unsigned int)pml->buf.length ));
669 DLIST_REMOVE(deferred_open_queue, pml);
670 TALLOC_FREE(pml);
671 return;
676 /****************************************************************************
677 Move a sharing violation open retry message to the front of the list and
678 schedule it for immediate processing.
679 ****************************************************************************/
681 void schedule_deferred_open_message_smb(uint64_t mid)
683 struct pending_message_list *pml;
684 int i = 0;
686 if (smbd_server_conn->using_smb2) {
687 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
688 return;
691 for (pml = deferred_open_queue; pml; pml = pml->next) {
692 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
694 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
695 "msg_mid = %llu\n",
696 i++,
697 (unsigned long long)msg_mid ));
699 if (mid == msg_mid) {
700 struct timed_event *te;
702 if (pml->processed) {
703 /* A processed message should not be
704 * rescheduled. */
705 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
706 "message mid %llu was already processed\n",
707 (unsigned long long)msg_mid ));
708 continue;
711 DEBUG(10,("schedule_deferred_open_message_smb: "
712 "scheduling mid %llu\n",
713 (unsigned long long)mid ));
715 te = event_add_timed(server_event_context(),
716 pml,
717 timeval_zero(),
718 smbd_deferred_open_timer,
719 pml);
720 if (!te) {
721 DEBUG(10,("schedule_deferred_open_message_smb: "
722 "event_add_timed() failed, "
723 "skipping mid %llu\n",
724 (unsigned long long)msg_mid ));
727 TALLOC_FREE(pml->te);
728 pml->te = te;
729 DLIST_PROMOTE(deferred_open_queue, pml);
730 return;
734 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
735 "find message mid %llu\n",
736 (unsigned long long)mid ));
739 /****************************************************************************
740 Return true if this mid is on the deferred queue and was not yet processed.
741 ****************************************************************************/
743 bool open_was_deferred(uint64_t mid)
745 struct pending_message_list *pml;
747 if (smbd_server_conn->using_smb2) {
748 return open_was_deferred_smb2(smbd_server_conn, mid);
751 for (pml = deferred_open_queue; pml; pml = pml->next) {
752 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
753 return True;
756 return False;
759 /****************************************************************************
760 Return the message queued by this mid.
761 ****************************************************************************/
763 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
765 struct pending_message_list *pml;
767 for (pml = deferred_open_queue; pml; pml = pml->next) {
768 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
769 return pml;
772 return NULL;
775 /****************************************************************************
776 Get the state data queued by this mid.
777 ****************************************************************************/
779 bool get_deferred_open_message_state(struct smb_request *smbreq,
780 struct timeval *p_request_time,
781 void **pp_state)
783 struct pending_message_list *pml;
785 if (smbd_server_conn->using_smb2) {
786 return get_deferred_open_message_state_smb2(smbreq->smb2req,
787 p_request_time,
788 pp_state);
791 pml = get_deferred_open_message_smb(smbreq->mid);
792 if (!pml) {
793 return false;
795 if (p_request_time) {
796 *p_request_time = pml->request_time;
798 if (pp_state) {
799 *pp_state = (void *)pml->private_data.data;
801 return true;
804 /****************************************************************************
805 Function to push a deferred open smb message onto a linked list of local smb
806 messages ready for processing.
807 ****************************************************************************/
809 bool push_deferred_open_message_smb(struct smb_request *req,
810 struct timeval request_time,
811 struct timeval timeout,
812 struct file_id id,
813 char *private_data, size_t priv_len)
815 struct timeval end_time;
817 if (req->smb2req) {
818 return push_deferred_open_message_smb2(req->smb2req,
819 request_time,
820 timeout,
822 private_data,
823 priv_len);
826 if (req->unread_bytes) {
827 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
828 "unread_bytes = %u\n",
829 (unsigned int)req->unread_bytes ));
830 smb_panic("push_deferred_open_message_smb: "
831 "logic error unread_bytes != 0" );
834 end_time = timeval_sum(&request_time, &timeout);
836 DEBUG(10,("push_deferred_open_message_smb: pushing message "
837 "len %u mid %llu timeout time [%u.%06u]\n",
838 (unsigned int) smb_len(req->inbuf)+4,
839 (unsigned long long)req->mid,
840 (unsigned int)end_time.tv_sec,
841 (unsigned int)end_time.tv_usec));
843 return push_queued_message(req, request_time, end_time,
844 private_data, priv_len);
847 static void smbd_sig_term_handler(struct tevent_context *ev,
848 struct tevent_signal *se,
849 int signum,
850 int count,
851 void *siginfo,
852 void *private_data)
854 exit_server_cleanly("termination signal");
857 void smbd_setup_sig_term_handler(void)
859 struct tevent_signal *se;
861 se = tevent_add_signal(server_event_context(),
862 server_event_context(),
863 SIGTERM, 0,
864 smbd_sig_term_handler,
865 NULL);
866 if (!se) {
867 exit_server("failed to setup SIGTERM handler");
871 static void smbd_sig_hup_handler(struct tevent_context *ev,
872 struct tevent_signal *se,
873 int signum,
874 int count,
875 void *siginfo,
876 void *private_data)
878 struct messaging_context *msg_ctx = talloc_get_type_abort(
879 private_data, struct messaging_context);
880 change_to_root_user();
881 DEBUG(1,("Reloading services after SIGHUP\n"));
882 reload_services(msg_ctx, smbd_server_conn->sock, False);
883 if (am_parent) {
884 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
888 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
889 struct messaging_context *msg_ctx)
891 struct tevent_signal *se;
893 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
894 msg_ctx);
895 if (!se) {
896 exit_server("failed to setup SIGHUP handler");
900 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
902 int timeout;
903 int num_pfds = 0;
904 int ret;
905 bool retry;
907 timeout = SMBD_SELECT_TIMEOUT * 1000;
910 * Are there any timed events waiting ? If so, ensure we don't
911 * select for longer than it would take to wait for them.
914 event_add_to_poll_args(server_event_context(), conn,
915 &conn->pfds, &num_pfds, &timeout);
917 /* Process a signal and timed events now... */
918 if (run_events_poll(server_event_context(), 0, NULL, 0)) {
919 return NT_STATUS_RETRY;
923 int sav;
924 START_PROFILE(smbd_idle);
926 ret = sys_poll(conn->pfds, num_pfds, timeout);
927 sav = errno;
929 END_PROFILE(smbd_idle);
930 errno = sav;
933 if (ret == -1) {
934 if (errno == EINTR) {
935 return NT_STATUS_RETRY;
937 return map_nt_error_from_unix(errno);
940 retry = run_events_poll(server_event_context(), ret, conn->pfds,
941 num_pfds);
942 if (retry) {
943 return NT_STATUS_RETRY;
946 /* Did we timeout ? */
947 if (ret == 0) {
948 return NT_STATUS_RETRY;
951 /* should not be reached */
952 return NT_STATUS_INTERNAL_ERROR;
956 * Only allow 5 outstanding trans requests. We're allocating memory, so
957 * prevent a DoS.
960 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
962 int count = 0;
963 for (; list != NULL; list = list->next) {
965 if (list->mid == mid) {
966 return NT_STATUS_INVALID_PARAMETER;
969 count += 1;
971 if (count > 5) {
972 return NT_STATUS_INSUFFICIENT_RESOURCES;
975 return NT_STATUS_OK;
979 These flags determine some of the permissions required to do an operation
981 Note that I don't set NEED_WRITE on some write operations because they
982 are used by some brain-dead clients when printing, and I don't want to
983 force write permissions on print services.
985 #define AS_USER (1<<0)
986 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
987 #define TIME_INIT (1<<2)
988 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
989 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
990 #define DO_CHDIR (1<<6)
993 define a list of possible SMB messages and their corresponding
994 functions. Any message that has a NULL function is unimplemented -
995 please feel free to contribute implementations!
997 static const struct smb_message_struct {
998 const char *name;
999 void (*fn)(struct smb_request *req);
1000 int flags;
1001 } smb_messages[256] = {
1003 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1004 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1005 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1006 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1007 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1008 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1009 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1010 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1011 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1012 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1013 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1014 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1015 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1016 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1017 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1018 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1019 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1020 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1021 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1022 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1023 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1024 /* 0x15 */ { NULL, NULL, 0 },
1025 /* 0x16 */ { NULL, NULL, 0 },
1026 /* 0x17 */ { NULL, NULL, 0 },
1027 /* 0x18 */ { NULL, NULL, 0 },
1028 /* 0x19 */ { NULL, NULL, 0 },
1029 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1030 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1031 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1032 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1033 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1034 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1035 /* 0x20 */ { "SMBwritec", NULL,0},
1036 /* 0x21 */ { NULL, NULL, 0 },
1037 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1038 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1039 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1040 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1041 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1042 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1043 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1044 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1045 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1046 /* 0x2b */ { "SMBecho",reply_echo,0},
1047 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1048 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1049 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1050 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1051 /* 0x30 */ { NULL, NULL, 0 },
1052 /* 0x31 */ { NULL, NULL, 0 },
1053 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1054 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1055 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1056 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1057 /* 0x36 */ { NULL, NULL, 0 },
1058 /* 0x37 */ { NULL, NULL, 0 },
1059 /* 0x38 */ { NULL, NULL, 0 },
1060 /* 0x39 */ { NULL, NULL, 0 },
1061 /* 0x3a */ { NULL, NULL, 0 },
1062 /* 0x3b */ { NULL, NULL, 0 },
1063 /* 0x3c */ { NULL, NULL, 0 },
1064 /* 0x3d */ { NULL, NULL, 0 },
1065 /* 0x3e */ { NULL, NULL, 0 },
1066 /* 0x3f */ { NULL, NULL, 0 },
1067 /* 0x40 */ { NULL, NULL, 0 },
1068 /* 0x41 */ { NULL, NULL, 0 },
1069 /* 0x42 */ { NULL, NULL, 0 },
1070 /* 0x43 */ { NULL, NULL, 0 },
1071 /* 0x44 */ { NULL, NULL, 0 },
1072 /* 0x45 */ { NULL, NULL, 0 },
1073 /* 0x46 */ { NULL, NULL, 0 },
1074 /* 0x47 */ { NULL, NULL, 0 },
1075 /* 0x48 */ { NULL, NULL, 0 },
1076 /* 0x49 */ { NULL, NULL, 0 },
1077 /* 0x4a */ { NULL, NULL, 0 },
1078 /* 0x4b */ { NULL, NULL, 0 },
1079 /* 0x4c */ { NULL, NULL, 0 },
1080 /* 0x4d */ { NULL, NULL, 0 },
1081 /* 0x4e */ { NULL, NULL, 0 },
1082 /* 0x4f */ { NULL, NULL, 0 },
1083 /* 0x50 */ { NULL, NULL, 0 },
1084 /* 0x51 */ { NULL, NULL, 0 },
1085 /* 0x52 */ { NULL, NULL, 0 },
1086 /* 0x53 */ { NULL, NULL, 0 },
1087 /* 0x54 */ { NULL, NULL, 0 },
1088 /* 0x55 */ { NULL, NULL, 0 },
1089 /* 0x56 */ { NULL, NULL, 0 },
1090 /* 0x57 */ { NULL, NULL, 0 },
1091 /* 0x58 */ { NULL, NULL, 0 },
1092 /* 0x59 */ { NULL, NULL, 0 },
1093 /* 0x5a */ { NULL, NULL, 0 },
1094 /* 0x5b */ { NULL, NULL, 0 },
1095 /* 0x5c */ { NULL, NULL, 0 },
1096 /* 0x5d */ { NULL, NULL, 0 },
1097 /* 0x5e */ { NULL, NULL, 0 },
1098 /* 0x5f */ { NULL, NULL, 0 },
1099 /* 0x60 */ { NULL, NULL, 0 },
1100 /* 0x61 */ { NULL, NULL, 0 },
1101 /* 0x62 */ { NULL, NULL, 0 },
1102 /* 0x63 */ { NULL, NULL, 0 },
1103 /* 0x64 */ { NULL, NULL, 0 },
1104 /* 0x65 */ { NULL, NULL, 0 },
1105 /* 0x66 */ { NULL, NULL, 0 },
1106 /* 0x67 */ { NULL, NULL, 0 },
1107 /* 0x68 */ { NULL, NULL, 0 },
1108 /* 0x69 */ { NULL, NULL, 0 },
1109 /* 0x6a */ { NULL, NULL, 0 },
1110 /* 0x6b */ { NULL, NULL, 0 },
1111 /* 0x6c */ { NULL, NULL, 0 },
1112 /* 0x6d */ { NULL, NULL, 0 },
1113 /* 0x6e */ { NULL, NULL, 0 },
1114 /* 0x6f */ { NULL, NULL, 0 },
1115 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1116 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1117 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1118 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1119 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1120 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1121 /* 0x76 */ { NULL, NULL, 0 },
1122 /* 0x77 */ { NULL, NULL, 0 },
1123 /* 0x78 */ { NULL, NULL, 0 },
1124 /* 0x79 */ { NULL, NULL, 0 },
1125 /* 0x7a */ { NULL, NULL, 0 },
1126 /* 0x7b */ { NULL, NULL, 0 },
1127 /* 0x7c */ { NULL, NULL, 0 },
1128 /* 0x7d */ { NULL, NULL, 0 },
1129 /* 0x7e */ { NULL, NULL, 0 },
1130 /* 0x7f */ { NULL, NULL, 0 },
1131 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1132 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1133 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1134 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1135 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1136 /* 0x85 */ { NULL, NULL, 0 },
1137 /* 0x86 */ { NULL, NULL, 0 },
1138 /* 0x87 */ { NULL, NULL, 0 },
1139 /* 0x88 */ { NULL, NULL, 0 },
1140 /* 0x89 */ { NULL, NULL, 0 },
1141 /* 0x8a */ { NULL, NULL, 0 },
1142 /* 0x8b */ { NULL, NULL, 0 },
1143 /* 0x8c */ { NULL, NULL, 0 },
1144 /* 0x8d */ { NULL, NULL, 0 },
1145 /* 0x8e */ { NULL, NULL, 0 },
1146 /* 0x8f */ { NULL, NULL, 0 },
1147 /* 0x90 */ { NULL, NULL, 0 },
1148 /* 0x91 */ { NULL, NULL, 0 },
1149 /* 0x92 */ { NULL, NULL, 0 },
1150 /* 0x93 */ { NULL, NULL, 0 },
1151 /* 0x94 */ { NULL, NULL, 0 },
1152 /* 0x95 */ { NULL, NULL, 0 },
1153 /* 0x96 */ { NULL, NULL, 0 },
1154 /* 0x97 */ { NULL, NULL, 0 },
1155 /* 0x98 */ { NULL, NULL, 0 },
1156 /* 0x99 */ { NULL, NULL, 0 },
1157 /* 0x9a */ { NULL, NULL, 0 },
1158 /* 0x9b */ { NULL, NULL, 0 },
1159 /* 0x9c */ { NULL, NULL, 0 },
1160 /* 0x9d */ { NULL, NULL, 0 },
1161 /* 0x9e */ { NULL, NULL, 0 },
1162 /* 0x9f */ { NULL, NULL, 0 },
1163 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1164 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1165 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1166 /* 0xa3 */ { NULL, NULL, 0 },
1167 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1168 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1169 /* 0xa6 */ { NULL, NULL, 0 },
1170 /* 0xa7 */ { NULL, NULL, 0 },
1171 /* 0xa8 */ { NULL, NULL, 0 },
1172 /* 0xa9 */ { NULL, NULL, 0 },
1173 /* 0xaa */ { NULL, NULL, 0 },
1174 /* 0xab */ { NULL, NULL, 0 },
1175 /* 0xac */ { NULL, NULL, 0 },
1176 /* 0xad */ { NULL, NULL, 0 },
1177 /* 0xae */ { NULL, NULL, 0 },
1178 /* 0xaf */ { NULL, NULL, 0 },
1179 /* 0xb0 */ { NULL, NULL, 0 },
1180 /* 0xb1 */ { NULL, NULL, 0 },
1181 /* 0xb2 */ { NULL, NULL, 0 },
1182 /* 0xb3 */ { NULL, NULL, 0 },
1183 /* 0xb4 */ { NULL, NULL, 0 },
1184 /* 0xb5 */ { NULL, NULL, 0 },
1185 /* 0xb6 */ { NULL, NULL, 0 },
1186 /* 0xb7 */ { NULL, NULL, 0 },
1187 /* 0xb8 */ { NULL, NULL, 0 },
1188 /* 0xb9 */ { NULL, NULL, 0 },
1189 /* 0xba */ { NULL, NULL, 0 },
1190 /* 0xbb */ { NULL, NULL, 0 },
1191 /* 0xbc */ { NULL, NULL, 0 },
1192 /* 0xbd */ { NULL, NULL, 0 },
1193 /* 0xbe */ { NULL, NULL, 0 },
1194 /* 0xbf */ { NULL, NULL, 0 },
1195 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1196 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1197 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1198 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1199 /* 0xc4 */ { NULL, NULL, 0 },
1200 /* 0xc5 */ { NULL, NULL, 0 },
1201 /* 0xc6 */ { NULL, NULL, 0 },
1202 /* 0xc7 */ { NULL, NULL, 0 },
1203 /* 0xc8 */ { NULL, NULL, 0 },
1204 /* 0xc9 */ { NULL, NULL, 0 },
1205 /* 0xca */ { NULL, NULL, 0 },
1206 /* 0xcb */ { NULL, NULL, 0 },
1207 /* 0xcc */ { NULL, NULL, 0 },
1208 /* 0xcd */ { NULL, NULL, 0 },
1209 /* 0xce */ { NULL, NULL, 0 },
1210 /* 0xcf */ { NULL, NULL, 0 },
1211 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1212 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1213 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1214 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1215 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1216 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1217 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1218 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1219 /* 0xd8 */ { NULL, NULL, 0 },
1220 /* 0xd9 */ { NULL, NULL, 0 },
1221 /* 0xda */ { NULL, NULL, 0 },
1222 /* 0xdb */ { NULL, NULL, 0 },
1223 /* 0xdc */ { NULL, NULL, 0 },
1224 /* 0xdd */ { NULL, NULL, 0 },
1225 /* 0xde */ { NULL, NULL, 0 },
1226 /* 0xdf */ { NULL, NULL, 0 },
1227 /* 0xe0 */ { NULL, NULL, 0 },
1228 /* 0xe1 */ { NULL, NULL, 0 },
1229 /* 0xe2 */ { NULL, NULL, 0 },
1230 /* 0xe3 */ { NULL, NULL, 0 },
1231 /* 0xe4 */ { NULL, NULL, 0 },
1232 /* 0xe5 */ { NULL, NULL, 0 },
1233 /* 0xe6 */ { NULL, NULL, 0 },
1234 /* 0xe7 */ { NULL, NULL, 0 },
1235 /* 0xe8 */ { NULL, NULL, 0 },
1236 /* 0xe9 */ { NULL, NULL, 0 },
1237 /* 0xea */ { NULL, NULL, 0 },
1238 /* 0xeb */ { NULL, NULL, 0 },
1239 /* 0xec */ { NULL, NULL, 0 },
1240 /* 0xed */ { NULL, NULL, 0 },
1241 /* 0xee */ { NULL, NULL, 0 },
1242 /* 0xef */ { NULL, NULL, 0 },
1243 /* 0xf0 */ { NULL, NULL, 0 },
1244 /* 0xf1 */ { NULL, NULL, 0 },
1245 /* 0xf2 */ { NULL, NULL, 0 },
1246 /* 0xf3 */ { NULL, NULL, 0 },
1247 /* 0xf4 */ { NULL, NULL, 0 },
1248 /* 0xf5 */ { NULL, NULL, 0 },
1249 /* 0xf6 */ { NULL, NULL, 0 },
1250 /* 0xf7 */ { NULL, NULL, 0 },
1251 /* 0xf8 */ { NULL, NULL, 0 },
1252 /* 0xf9 */ { NULL, NULL, 0 },
1253 /* 0xfa */ { NULL, NULL, 0 },
1254 /* 0xfb */ { NULL, NULL, 0 },
1255 /* 0xfc */ { NULL, NULL, 0 },
1256 /* 0xfd */ { NULL, NULL, 0 },
1257 /* 0xfe */ { NULL, NULL, 0 },
1258 /* 0xff */ { NULL, NULL, 0 }
1262 /*******************************************************************
1263 allocate and initialize a reply packet
1264 ********************************************************************/
1266 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1267 const char *inbuf, char **outbuf, uint8_t num_words,
1268 uint32_t num_bytes)
1271 * Protect against integer wrap
1273 if ((num_bytes > 0xffffff)
1274 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1275 char *msg;
1276 if (asprintf(&msg, "num_bytes too large: %u",
1277 (unsigned)num_bytes) == -1) {
1278 msg = discard_const_p(char, "num_bytes too large");
1280 smb_panic(msg);
1283 *outbuf = talloc_array(mem_ctx, char,
1284 smb_size + num_words*2 + num_bytes);
1285 if (*outbuf == NULL) {
1286 return false;
1289 construct_reply_common(req, inbuf, *outbuf);
1290 srv_set_message(*outbuf, num_words, num_bytes, false);
1292 * Zero out the word area, the caller has to take care of the bcc area
1293 * himself
1295 if (num_words != 0) {
1296 memset(*outbuf + smb_vwv0, 0, num_words*2);
1299 return true;
1302 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1304 char *outbuf;
1305 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1306 num_bytes)) {
1307 smb_panic("could not allocate output buffer\n");
1309 req->outbuf = (uint8_t *)outbuf;
1313 /*******************************************************************
1314 Dump a packet to a file.
1315 ********************************************************************/
1317 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1319 int fd, i;
1320 char *fname = NULL;
1321 if (DEBUGLEVEL < 50) {
1322 return;
1325 if (len < 4) len = smb_len(data)+4;
1326 for (i=1;i<100;i++) {
1327 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1328 type ? "req" : "resp") == -1) {
1329 return;
1331 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1332 if (fd != -1 || errno != EEXIST) break;
1334 if (fd != -1) {
1335 ssize_t ret = write(fd, data, len);
1336 if (ret != len)
1337 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1338 close(fd);
1339 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1341 SAFE_FREE(fname);
1344 /****************************************************************************
1345 Prepare everything for calling the actual request function, and potentially
1346 call the request function via the "new" interface.
1348 Return False if the "legacy" function needs to be called, everything is
1349 prepared.
1351 Return True if we're done.
1353 I know this API sucks, but it is the one with the least code change I could
1354 find.
1355 ****************************************************************************/
1357 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1359 int flags;
1360 uint16 session_tag;
1361 connection_struct *conn = NULL;
1362 struct smbd_server_connection *sconn = req->sconn;
1363 char *raddr;
1365 errno = 0;
1367 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1368 * so subtract 4 from it. */
1369 if (!valid_smb_header(req->inbuf)
1370 || (size < (smb_size - 4))) {
1371 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1372 smb_len(req->inbuf)));
1373 exit_server_cleanly("Non-SMB packet");
1376 if (smb_messages[type].fn == NULL) {
1377 DEBUG(0,("Unknown message type %d!\n",type));
1378 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1379 reply_unknown_new(req, type);
1380 return NULL;
1383 flags = smb_messages[type].flags;
1385 /* In share mode security we must ignore the vuid. */
1386 session_tag = (lp_security() == SEC_SHARE)
1387 ? UID_FIELD_INVALID : req->vuid;
1388 conn = req->conn;
1390 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1391 (int)sys_getpid(), (unsigned long)conn));
1393 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1395 /* Ensure this value is replaced in the incoming packet. */
1396 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1399 * Ensure the correct username is in current_user_info. This is a
1400 * really ugly bugfix for problems with multiple session_setup_and_X's
1401 * being done and allowing %U and %G substitutions to work correctly.
1402 * There is a reason this code is done here, don't move it unless you
1403 * know what you're doing... :-).
1404 * JRA.
1407 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1408 user_struct *vuser = NULL;
1410 sconn->smb1.sessions.last_session_tag = session_tag;
1411 if(session_tag != UID_FIELD_INVALID) {
1412 vuser = get_valid_user_struct(sconn, session_tag);
1413 if (vuser) {
1414 set_current_user_info(
1415 vuser->session_info->sanitized_username,
1416 vuser->session_info->unix_name,
1417 vuser->session_info->info3->base.domain.string);
1422 /* Does this call need to be run as the connected user? */
1423 if (flags & AS_USER) {
1425 /* Does this call need a valid tree connection? */
1426 if (!conn) {
1428 * Amazingly, the error code depends on the command
1429 * (from Samba4).
1431 if (type == SMBntcreateX) {
1432 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1433 } else {
1434 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1436 return NULL;
1439 if (!change_to_user(conn,session_tag)) {
1440 DEBUG(0, ("Error: Could not change to user. Removing "
1441 "deferred open, mid=%llu.\n",
1442 (unsigned long long)req->mid));
1443 reply_force_doserror(req, ERRSRV, ERRbaduid);
1444 return conn;
1447 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1449 /* Does it need write permission? */
1450 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1451 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1452 return conn;
1455 /* IPC services are limited */
1456 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1457 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1458 return conn;
1460 } else {
1461 /* This call needs to be run as root */
1462 change_to_root_user();
1465 /* load service specific parameters */
1466 if (conn) {
1467 if (req->encrypted) {
1468 conn->encrypted_tid = true;
1469 /* encrypted required from now on. */
1470 conn->encrypt_level = Required;
1471 } else if (ENCRYPTION_REQUIRED(conn)) {
1472 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1473 exit_server_cleanly("encryption required "
1474 "on connection");
1475 return conn;
1479 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1480 (flags & (AS_USER|DO_CHDIR)
1481 ?True:False))) {
1482 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1483 return conn;
1485 conn->num_smb_operations++;
1488 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1489 talloc_tos());
1490 if (raddr == NULL) {
1491 reply_nterror(req, NT_STATUS_NO_MEMORY);
1492 return conn;
1495 /* does this protocol need to be run as guest? */
1496 if ((flags & AS_GUEST)
1497 && (!change_to_guest() ||
1498 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1499 sconn->remote_hostname,
1500 raddr))) {
1501 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1502 return conn;
1505 smb_messages[type].fn(req);
1506 return req->conn;
1509 /****************************************************************************
1510 Construct a reply to the incoming packet.
1511 ****************************************************************************/
1513 static void construct_reply(struct smbd_server_connection *sconn,
1514 char *inbuf, int size, size_t unread_bytes,
1515 uint32_t seqnum, bool encrypted,
1516 struct smb_perfcount_data *deferred_pcd)
1518 connection_struct *conn;
1519 struct smb_request *req;
1521 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1522 smb_panic("could not allocate smb_request");
1525 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1526 encrypted, seqnum)) {
1527 exit_server_cleanly("Invalid SMB request");
1530 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1532 /* we popped this message off the queue - keep original perf data */
1533 if (deferred_pcd)
1534 req->pcd = *deferred_pcd;
1535 else {
1536 SMB_PERFCOUNT_START(&req->pcd);
1537 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1538 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1541 conn = switch_message(req->cmd, req, size);
1543 if (req->unread_bytes) {
1544 /* writeX failed. drain socket. */
1545 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1546 req->unread_bytes) {
1547 smb_panic("failed to drain pending bytes");
1549 req->unread_bytes = 0;
1552 if (req->done) {
1553 TALLOC_FREE(req);
1554 return;
1557 if (req->outbuf == NULL) {
1558 return;
1561 if (CVAL(req->outbuf,0) == 0) {
1562 show_msg((char *)req->outbuf);
1565 if (!srv_send_smb(req->sconn,
1566 (char *)req->outbuf,
1567 true, req->seqnum+1,
1568 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1569 &req->pcd)) {
1570 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1573 TALLOC_FREE(req);
1575 return;
1578 /****************************************************************************
1579 Process an smb from the client
1580 ****************************************************************************/
1581 static void process_smb(struct smbd_server_connection *sconn,
1582 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1583 uint32_t seqnum, bool encrypted,
1584 struct smb_perfcount_data *deferred_pcd)
1586 int msg_type = CVAL(inbuf,0);
1588 DO_PROFILE_INC(smb_count);
1590 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1591 smb_len(inbuf) ) );
1592 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1593 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1595 if (msg_type != 0) {
1597 * NetBIOS session request, keepalive, etc.
1599 reply_special(sconn, (char *)inbuf, nread);
1600 goto done;
1603 if (sconn->using_smb2) {
1604 /* At this point we're not really using smb2,
1605 * we make the decision here.. */
1606 if (smbd_is_smb2_header(inbuf, nread)) {
1607 smbd_smb2_first_negprot(sconn, inbuf, nread);
1608 return;
1609 } else if (nread >= smb_size && valid_smb_header(inbuf)
1610 && CVAL(inbuf, smb_com) != 0x72) {
1611 /* This is a non-negprot SMB1 packet.
1612 Disable SMB2 from now on. */
1613 sconn->using_smb2 = false;
1617 show_msg((char *)inbuf);
1619 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1620 encrypted, deferred_pcd);
1621 sconn->trans_num++;
1623 done:
1624 sconn->num_requests++;
1626 /* The timeout_processing function isn't run nearly
1627 often enough to implement 'max log size' without
1628 overrunning the size of the file by many megabytes.
1629 This is especially true if we are running at debug
1630 level 10. Checking every 50 SMBs is a nice
1631 tradeoff of performance vs log file size overrun. */
1633 if ((sconn->num_requests % 50) == 0 &&
1634 need_to_check_log_size()) {
1635 change_to_root_user();
1636 check_log_size();
1640 /****************************************************************************
1641 Return a string containing the function name of a SMB command.
1642 ****************************************************************************/
1644 const char *smb_fn_name(int type)
1646 const char *unknown_name = "SMBunknown";
1648 if (smb_messages[type].name == NULL)
1649 return(unknown_name);
1651 return(smb_messages[type].name);
1654 /****************************************************************************
1655 Helper functions for contruct_reply.
1656 ****************************************************************************/
1658 void add_to_common_flags2(uint32 v)
1660 common_flags2 |= v;
1663 void remove_from_common_flags2(uint32 v)
1665 common_flags2 &= ~v;
1668 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1669 char *outbuf)
1671 srv_set_message(outbuf,0,0,false);
1673 SCVAL(outbuf, smb_com, req->cmd);
1674 SIVAL(outbuf,smb_rcls,0);
1675 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1676 SSVAL(outbuf,smb_flg2,
1677 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1678 common_flags2);
1679 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1681 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1682 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1683 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1684 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1687 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1689 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1693 * How many bytes have we already accumulated up to the current wct field
1694 * offset?
1697 size_t req_wct_ofs(struct smb_request *req)
1699 size_t buf_size;
1701 if (req->chain_outbuf == NULL) {
1702 return smb_wct - 4;
1704 buf_size = talloc_get_size(req->chain_outbuf);
1705 if ((buf_size % 4) != 0) {
1706 buf_size += (4 - (buf_size % 4));
1708 return buf_size - 4;
1712 * Hack around reply_nterror & friends not being aware of chained requests,
1713 * generating illegal (i.e. wct==0) chain replies.
1716 static void fixup_chain_error_packet(struct smb_request *req)
1718 uint8_t *outbuf = req->outbuf;
1719 req->outbuf = NULL;
1720 reply_outbuf(req, 2, 0);
1721 memcpy(req->outbuf, outbuf, smb_wct);
1722 TALLOC_FREE(outbuf);
1723 SCVAL(req->outbuf, smb_vwv0, 0xff);
1727 * @brief Find the smb_cmd offset of the last command pushed
1728 * @param[in] buf The buffer we're building up
1729 * @retval Where can we put our next andx cmd?
1731 * While chaining requests, the "next" request we're looking at needs to put
1732 * its SMB_Command before the data the previous request already built up added
1733 * to the chain. Find the offset to the place where we have to put our cmd.
1736 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1738 uint8_t cmd;
1739 size_t ofs;
1741 cmd = CVAL(buf, smb_com);
1743 SMB_ASSERT(is_andx_req(cmd));
1745 ofs = smb_vwv0;
1747 while (CVAL(buf, ofs) != 0xff) {
1749 if (!is_andx_req(CVAL(buf, ofs))) {
1750 return false;
1754 * ofs is from start of smb header, so add the 4 length
1755 * bytes. The next cmd is right after the wct field.
1757 ofs = SVAL(buf, ofs+2) + 4 + 1;
1759 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1762 *pofs = ofs;
1763 return true;
1767 * @brief Do the smb chaining at a buffer level
1768 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1769 * @param[in] smb_command The command that we want to issue
1770 * @param[in] wct How many words?
1771 * @param[in] vwv The words, already in network order
1772 * @param[in] bytes_alignment How shall we align "bytes"?
1773 * @param[in] num_bytes How many bytes?
1774 * @param[in] bytes The data the request ships
1776 * smb_splice_chain() adds the vwv and bytes to the request already present in
1777 * *poutbuf.
1780 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1781 uint8_t wct, const uint16_t *vwv,
1782 size_t bytes_alignment,
1783 uint32_t num_bytes, const uint8_t *bytes)
1785 uint8_t *outbuf;
1786 size_t old_size, new_size;
1787 size_t ofs;
1788 size_t chain_padding = 0;
1789 size_t bytes_padding = 0;
1790 bool first_request;
1792 old_size = talloc_get_size(*poutbuf);
1795 * old_size == smb_wct means we're pushing the first request in for
1796 * libsmb/
1799 first_request = (old_size == smb_wct);
1801 if (!first_request && ((old_size % 4) != 0)) {
1803 * Align the wct field of subsequent requests to a 4-byte
1804 * boundary
1806 chain_padding = 4 - (old_size % 4);
1810 * After the old request comes the new wct field (1 byte), the vwv's
1811 * and the num_bytes field. After at we might need to align the bytes
1812 * given to us to "bytes_alignment", increasing the num_bytes value.
1815 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1817 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1818 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1821 new_size += bytes_padding + num_bytes;
1823 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1824 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1825 (unsigned)new_size));
1826 return false;
1829 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1830 if (outbuf == NULL) {
1831 DEBUG(0, ("talloc failed\n"));
1832 return false;
1834 *poutbuf = outbuf;
1836 if (first_request) {
1837 SCVAL(outbuf, smb_com, smb_command);
1838 } else {
1839 size_t andx_cmd_ofs;
1841 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1842 DEBUG(1, ("invalid command chain\n"));
1843 *poutbuf = talloc_realloc(
1844 NULL, *poutbuf, uint8_t, old_size);
1845 return false;
1848 if (chain_padding != 0) {
1849 memset(outbuf + old_size, 0, chain_padding);
1850 old_size += chain_padding;
1853 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1854 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1857 ofs = old_size;
1860 * Push the chained request:
1862 * wct field
1865 SCVAL(outbuf, ofs, wct);
1866 ofs += 1;
1869 * vwv array
1872 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1873 ofs += sizeof(uint16_t) * wct;
1876 * bcc (byte count)
1879 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1880 ofs += sizeof(uint16_t);
1883 * padding
1886 if (bytes_padding != 0) {
1887 memset(outbuf + ofs, 0, bytes_padding);
1888 ofs += bytes_padding;
1892 * The bytes field
1895 memcpy(outbuf + ofs, bytes, num_bytes);
1897 return true;
1900 /****************************************************************************
1901 Construct a chained reply and add it to the already made reply
1902 ****************************************************************************/
1904 void chain_reply(struct smb_request *req)
1906 size_t smblen = smb_len(req->inbuf);
1907 size_t already_used, length_needed;
1908 uint8_t chain_cmd;
1909 uint32_t chain_offset; /* uint32_t to avoid overflow */
1911 uint8_t wct;
1912 const uint16_t *vwv;
1913 uint16_t buflen;
1914 const uint8_t *buf;
1916 if (IVAL(req->outbuf, smb_rcls) != 0) {
1917 fixup_chain_error_packet(req);
1921 * Any of the AndX requests and replies have at least a wct of
1922 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1923 * beginning of the SMB header to the next wct field.
1925 * None of the AndX requests put anything valuable in vwv[0] and [1],
1926 * so we can overwrite it here to form the chain.
1929 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1930 if (req->chain_outbuf == NULL) {
1931 req->chain_outbuf = talloc_realloc(
1932 req, req->outbuf, uint8_t,
1933 smb_len(req->outbuf) + 4);
1934 if (req->chain_outbuf == NULL) {
1935 smb_panic("talloc failed");
1938 req->outbuf = NULL;
1939 goto error;
1943 * Here we assume that this is the end of the chain. For that we need
1944 * to set "next command" to 0xff and the offset to 0. If we later find
1945 * more commands in the chain, this will be overwritten again.
1948 SCVAL(req->outbuf, smb_vwv0, 0xff);
1949 SCVAL(req->outbuf, smb_vwv0+1, 0);
1950 SSVAL(req->outbuf, smb_vwv1, 0);
1952 if (req->chain_outbuf == NULL) {
1954 * In req->chain_outbuf we collect all the replies. Start the
1955 * chain by copying in the first reply.
1957 * We do the realloc because later on we depend on
1958 * talloc_get_size to determine the length of
1959 * chain_outbuf. The reply_xxx routines might have
1960 * over-allocated (reply_pipe_read_and_X used to be such an
1961 * example).
1963 req->chain_outbuf = talloc_realloc(
1964 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1965 if (req->chain_outbuf == NULL) {
1966 smb_panic("talloc failed");
1968 req->outbuf = NULL;
1969 } else {
1971 * Update smb headers where subsequent chained commands
1972 * may have updated them.
1974 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1975 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1977 if (!smb_splice_chain(&req->chain_outbuf,
1978 CVAL(req->outbuf, smb_com),
1979 CVAL(req->outbuf, smb_wct),
1980 (uint16_t *)(req->outbuf + smb_vwv),
1981 0, smb_buflen(req->outbuf),
1982 (uint8_t *)smb_buf(req->outbuf))) {
1983 goto error;
1985 TALLOC_FREE(req->outbuf);
1989 * We use the old request's vwv field to grab the next chained command
1990 * and offset into the chained fields.
1993 chain_cmd = CVAL(req->vwv+0, 0);
1994 chain_offset = SVAL(req->vwv+1, 0);
1996 if (chain_cmd == 0xff) {
1998 * End of chain, no more requests from the client. So ship the
1999 * replies.
2001 smb_setlen((char *)(req->chain_outbuf),
2002 talloc_get_size(req->chain_outbuf) - 4);
2004 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2005 true, req->seqnum+1,
2006 IS_CONN_ENCRYPTED(req->conn)
2007 ||req->encrypted,
2008 &req->pcd)) {
2009 exit_server_cleanly("chain_reply: srv_send_smb "
2010 "failed.");
2012 TALLOC_FREE(req->chain_outbuf);
2013 req->done = true;
2014 return;
2017 /* add a new perfcounter for this element of chain */
2018 SMB_PERFCOUNT_ADD(&req->pcd);
2019 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2020 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2023 * Check if the client tries to fool us. The request so far uses the
2024 * space to the end of the byte buffer in the request just
2025 * processed. The chain_offset can't point into that area. If that was
2026 * the case, we could end up with an endless processing of the chain,
2027 * we would always handle the same request.
2030 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2031 if (chain_offset < already_used) {
2032 goto error;
2036 * Next check: Make sure the chain offset does not point beyond the
2037 * overall smb request length.
2040 length_needed = chain_offset+1; /* wct */
2041 if (length_needed > smblen) {
2042 goto error;
2046 * Now comes the pointer magic. Goal here is to set up req->vwv and
2047 * req->buf correctly again to be able to call the subsequent
2048 * switch_message(). The chain offset (the former vwv[1]) points at
2049 * the new wct field.
2052 wct = CVAL(smb_base(req->inbuf), chain_offset);
2055 * Next consistency check: Make the new vwv array fits in the overall
2056 * smb request.
2059 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2060 if (length_needed > smblen) {
2061 goto error;
2063 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2066 * Now grab the new byte buffer....
2069 buflen = SVAL(vwv+wct, 0);
2072 * .. and check that it fits.
2075 length_needed += buflen;
2076 if (length_needed > smblen) {
2077 goto error;
2079 buf = (const uint8_t *)(vwv+wct+1);
2081 req->cmd = chain_cmd;
2082 req->wct = wct;
2083 req->vwv = discard_const_p(uint16_t, vwv);
2084 req->buflen = buflen;
2085 req->buf = buf;
2087 switch_message(chain_cmd, req, smblen);
2089 if (req->outbuf == NULL) {
2091 * This happens if the chained command has suspended itself or
2092 * if it has called srv_send_smb() itself.
2094 return;
2098 * We end up here if the chained command was not itself chained or
2099 * suspended, but for example a close() command. We now need to splice
2100 * the chained commands' outbuf into the already built up chain_outbuf
2101 * and ship the result.
2103 goto done;
2105 error:
2107 * We end up here if there's any error in the chain syntax. Report a
2108 * DOS error, just like Windows does.
2110 reply_force_doserror(req, ERRSRV, ERRerror);
2111 fixup_chain_error_packet(req);
2113 done:
2115 * This scary statement intends to set the
2116 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2117 * to the value req->outbuf carries
2119 SSVAL(req->chain_outbuf, smb_flg2,
2120 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2121 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2124 * Transfer the error codes from the subrequest to the main one
2126 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2127 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2129 if (!smb_splice_chain(&req->chain_outbuf,
2130 CVAL(req->outbuf, smb_com),
2131 CVAL(req->outbuf, smb_wct),
2132 (uint16_t *)(req->outbuf + smb_vwv),
2133 0, smb_buflen(req->outbuf),
2134 (uint8_t *)smb_buf(req->outbuf))) {
2135 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2137 TALLOC_FREE(req->outbuf);
2139 smb_setlen((char *)(req->chain_outbuf),
2140 talloc_get_size(req->chain_outbuf) - 4);
2142 show_msg((char *)(req->chain_outbuf));
2144 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2145 true, req->seqnum+1,
2146 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2147 &req->pcd)) {
2148 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2150 TALLOC_FREE(req->chain_outbuf);
2151 req->done = true;
2154 /****************************************************************************
2155 Check if services need reloading.
2156 ****************************************************************************/
2158 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2161 if (last_smb_conf_reload_time == 0) {
2162 last_smb_conf_reload_time = t;
2165 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2166 reload_services(sconn->msg_ctx, sconn->sock, True);
2167 last_smb_conf_reload_time = t;
2171 static bool fd_is_readable(int fd)
2173 int ret, revents;
2175 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2177 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2181 static void smbd_server_connection_write_handler(
2182 struct smbd_server_connection *sconn)
2184 /* TODO: make write nonblocking */
2187 static void smbd_server_connection_read_handler(
2188 struct smbd_server_connection *sconn, int fd)
2190 uint8_t *inbuf = NULL;
2191 size_t inbuf_len = 0;
2192 size_t unread_bytes = 0;
2193 bool encrypted = false;
2194 TALLOC_CTX *mem_ctx = talloc_tos();
2195 NTSTATUS status;
2196 uint32_t seqnum;
2198 bool from_client = (sconn->sock == fd);
2200 if (from_client) {
2201 smbd_lock_socket(sconn);
2203 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2204 DEBUG(10,("the echo listener was faster\n"));
2205 smbd_unlock_socket(sconn);
2206 return;
2209 /* TODO: make this completely nonblocking */
2210 status = receive_smb_talloc(mem_ctx, sconn, fd,
2211 (char **)(void *)&inbuf,
2212 0, /* timeout */
2213 &unread_bytes,
2214 &encrypted,
2215 &inbuf_len, &seqnum,
2216 false /* trusted channel */);
2217 smbd_unlock_socket(sconn);
2218 } else {
2219 /* TODO: make this completely nonblocking */
2220 status = receive_smb_talloc(mem_ctx, sconn, fd,
2221 (char **)(void *)&inbuf,
2222 0, /* timeout */
2223 &unread_bytes,
2224 &encrypted,
2225 &inbuf_len, &seqnum,
2226 true /* trusted channel */);
2229 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2230 goto process;
2232 if (NT_STATUS_IS_ERR(status)) {
2233 exit_server_cleanly("failed to receive smb request");
2235 if (!NT_STATUS_IS_OK(status)) {
2236 return;
2239 process:
2240 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2241 seqnum, encrypted, NULL);
2244 static void smbd_server_connection_handler(struct event_context *ev,
2245 struct fd_event *fde,
2246 uint16_t flags,
2247 void *private_data)
2249 struct smbd_server_connection *conn = talloc_get_type(private_data,
2250 struct smbd_server_connection);
2252 if (flags & EVENT_FD_WRITE) {
2253 smbd_server_connection_write_handler(conn);
2254 return;
2256 if (flags & EVENT_FD_READ) {
2257 smbd_server_connection_read_handler(conn, conn->sock);
2258 return;
2262 static void smbd_server_echo_handler(struct event_context *ev,
2263 struct fd_event *fde,
2264 uint16_t flags,
2265 void *private_data)
2267 struct smbd_server_connection *conn = talloc_get_type(private_data,
2268 struct smbd_server_connection);
2270 if (flags & EVENT_FD_WRITE) {
2271 smbd_server_connection_write_handler(conn);
2272 return;
2274 if (flags & EVENT_FD_READ) {
2275 smbd_server_connection_read_handler(
2276 conn, conn->smb1.echo_handler.trusted_fd);
2277 return;
2281 #ifdef CLUSTER_SUPPORT
2282 /****************************************************************************
2283 received when we should release a specific IP
2284 ****************************************************************************/
2285 static void release_ip(const char *ip, void *priv)
2287 const char *addr = (const char *)priv;
2288 const char *p = addr;
2290 if (strncmp("::ffff:", addr, 7) == 0) {
2291 p = addr + 7;
2294 DEBUG(10, ("Got release IP message for %s, "
2295 "our address is %s\n", ip, p));
2297 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2298 /* we can't afford to do a clean exit - that involves
2299 database writes, which would potentially mean we
2300 are still running after the failover has finished -
2301 we have to get rid of this process ID straight
2302 away */
2303 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2304 ip));
2305 /* note we must exit with non-zero status so the unclean handler gets
2306 called in the parent, so that the brl database is tickled */
2307 _exit(1);
2311 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2312 struct sockaddr_storage *client)
2314 socklen_t length;
2315 length = sizeof(*server);
2316 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2317 return -1;
2319 length = sizeof(*client);
2320 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2321 return -1;
2323 return 0;
2325 #endif
2328 * Send keepalive packets to our client
2330 static bool keepalive_fn(const struct timeval *now, void *private_data)
2332 struct smbd_server_connection *sconn = smbd_server_conn;
2333 bool ret;
2335 if (sconn->using_smb2) {
2336 /* Don't do keepalives on an SMB2 connection. */
2337 return false;
2340 smbd_lock_socket(smbd_server_conn);
2341 ret = send_keepalive(sconn->sock);
2342 smbd_unlock_socket(smbd_server_conn);
2344 if (!ret) {
2345 char addr[INET6_ADDRSTRLEN];
2347 * Try and give an error message saying what
2348 * client failed.
2350 DEBUG(0, ("send_keepalive failed for client %s. "
2351 "Error %s - exiting\n",
2352 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2353 strerror(errno)));
2354 return False;
2356 return True;
2360 * Do the recurring check if we're idle
2362 static bool deadtime_fn(const struct timeval *now, void *private_data)
2364 struct smbd_server_connection *sconn =
2365 (struct smbd_server_connection *)private_data;
2367 if ((conn_num_open(sconn) == 0)
2368 || (conn_idle_all(sconn, now->tv_sec))) {
2369 DEBUG( 2, ( "Closing idle connection\n" ) );
2370 messaging_send(sconn->msg_ctx,
2371 messaging_server_id(sconn->msg_ctx),
2372 MSG_SHUTDOWN, &data_blob_null);
2373 return False;
2376 return True;
2380 * Do the recurring log file and smb.conf reload checks.
2383 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2385 struct smbd_server_connection *sconn = talloc_get_type_abort(
2386 private_data, struct smbd_server_connection);
2388 DEBUG(5, ("housekeeping\n"));
2390 change_to_root_user();
2392 /* update printer queue caches if necessary */
2393 update_monitored_printq_cache(sconn->msg_ctx);
2395 /* check if we need to reload services */
2396 check_reload(sconn, time_mono(NULL));
2398 /* Change machine password if neccessary. */
2399 attempt_machine_password_change();
2402 * Force a log file check.
2404 force_check_log_size();
2405 check_log_size();
2406 return true;
2409 static int create_unlink_tmp(const char *dir)
2411 char *fname;
2412 int fd;
2414 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2415 if (fname == NULL) {
2416 errno = ENOMEM;
2417 return -1;
2419 fd = mkstemp(fname);
2420 if (fd == -1) {
2421 TALLOC_FREE(fname);
2422 return -1;
2424 if (unlink(fname) == -1) {
2425 int sys_errno = errno;
2426 close(fd);
2427 TALLOC_FREE(fname);
2428 errno = sys_errno;
2429 return -1;
2431 TALLOC_FREE(fname);
2432 return fd;
2435 struct smbd_echo_state {
2436 struct tevent_context *ev;
2437 struct iovec *pending;
2438 struct smbd_server_connection *sconn;
2439 int parent_pipe;
2441 struct tevent_fd *parent_fde;
2443 struct tevent_fd *read_fde;
2444 struct tevent_req *write_req;
2447 static void smbd_echo_writer_done(struct tevent_req *req);
2449 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2451 int num_pending;
2453 if (state->write_req != NULL) {
2454 return;
2457 num_pending = talloc_array_length(state->pending);
2458 if (num_pending == 0) {
2459 return;
2462 state->write_req = writev_send(state, state->ev, NULL,
2463 state->parent_pipe, false,
2464 state->pending, num_pending);
2465 if (state->write_req == NULL) {
2466 DEBUG(1, ("writev_send failed\n"));
2467 exit(1);
2470 talloc_steal(state->write_req, state->pending);
2471 state->pending = NULL;
2473 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2474 state);
2477 static void smbd_echo_writer_done(struct tevent_req *req)
2479 struct smbd_echo_state *state = tevent_req_callback_data(
2480 req, struct smbd_echo_state);
2481 ssize_t written;
2482 int err;
2484 written = writev_recv(req, &err);
2485 TALLOC_FREE(req);
2486 state->write_req = NULL;
2487 if (written == -1) {
2488 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2489 exit(1);
2491 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2492 smbd_echo_activate_writer(state);
2495 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2496 uint32_t seqnum)
2498 struct smb_request req;
2499 uint16_t num_replies;
2500 size_t out_len;
2501 char *outbuf;
2502 bool ok;
2504 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2505 DEBUG(10, ("Got netbios keepalive\n"));
2507 * Just swallow it
2509 return true;
2512 if (inbuf_len < smb_size) {
2513 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2514 return false;
2516 if (!valid_smb_header(inbuf)) {
2517 DEBUG(10, ("Got invalid SMB header\n"));
2518 return false;
2521 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2522 seqnum)) {
2523 return false;
2525 req.inbuf = inbuf;
2527 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2528 smb_messages[req.cmd].name
2529 ? smb_messages[req.cmd].name : "unknown"));
2531 if (req.cmd != SMBecho) {
2532 return false;
2534 if (req.wct < 1) {
2535 return false;
2538 num_replies = SVAL(req.vwv+0, 0);
2539 if (num_replies != 1) {
2540 /* Not a Windows "Hey, you're still there?" request */
2541 return false;
2544 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2545 1, req.buflen)) {
2546 DEBUG(10, ("create_outbuf failed\n"));
2547 return false;
2549 req.outbuf = (uint8_t *)outbuf;
2551 SSVAL(req.outbuf, smb_vwv0, num_replies);
2553 if (req.buflen > 0) {
2554 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2557 out_len = smb_len(req.outbuf) + 4;
2559 ok = srv_send_smb(req.sconn,
2560 (char *)outbuf,
2561 true, seqnum+1,
2562 false, &req.pcd);
2563 TALLOC_FREE(outbuf);
2564 if (!ok) {
2565 exit(1);
2568 return true;
2571 static void smbd_echo_exit(struct tevent_context *ev,
2572 struct tevent_fd *fde, uint16_t flags,
2573 void *private_data)
2575 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2576 exit(0);
2579 static void smbd_echo_reader(struct tevent_context *ev,
2580 struct tevent_fd *fde, uint16_t flags,
2581 void *private_data)
2583 struct smbd_echo_state *state = talloc_get_type_abort(
2584 private_data, struct smbd_echo_state);
2585 struct smbd_server_connection *sconn = state->sconn;
2586 size_t unread, num_pending;
2587 NTSTATUS status;
2588 struct iovec *tmp;
2589 size_t iov_len;
2590 uint32_t seqnum = 0;
2591 bool reply;
2592 bool ok;
2593 bool encrypted = false;
2595 smb_msleep(1000);
2597 ok = smbd_lock_socket_internal(sconn);
2598 if (!ok) {
2599 DEBUG(0, ("%s: failed to lock socket\n",
2600 __location__));
2601 exit(1);
2604 if (!fd_is_readable(sconn->sock)) {
2605 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2606 (int)sys_getpid()));
2607 ok = smbd_unlock_socket_internal(sconn);
2608 if (!ok) {
2609 DEBUG(1, ("%s: failed to unlock socket in\n",
2610 __location__));
2611 exit(1);
2613 return;
2616 num_pending = talloc_array_length(state->pending);
2617 tmp = talloc_realloc(state, state->pending, struct iovec,
2618 num_pending+1);
2619 if (tmp == NULL) {
2620 DEBUG(1, ("talloc_realloc failed\n"));
2621 exit(1);
2623 state->pending = tmp;
2625 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2627 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2628 (char **)(void *)&state->pending[num_pending].iov_base,
2629 0 /* timeout */,
2630 &unread,
2631 &encrypted,
2632 &iov_len,
2633 &seqnum,
2634 false /* trusted_channel*/);
2635 if (!NT_STATUS_IS_OK(status)) {
2636 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2637 (int)sys_getpid(), nt_errstr(status)));
2638 exit(1);
2640 state->pending[num_pending].iov_len = iov_len;
2642 ok = smbd_unlock_socket_internal(sconn);
2643 if (!ok) {
2644 DEBUG(1, ("%s: failed to unlock socket in\n",
2645 __location__));
2646 exit(1);
2649 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2650 state->pending[num_pending].iov_len,
2651 seqnum);
2652 if (reply) {
2653 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2654 /* no check, shrinking by some bytes does not fail */
2655 state->pending = talloc_realloc(state, state->pending,
2656 struct iovec,
2657 num_pending);
2658 return;
2661 if (state->pending[num_pending].iov_len >= smb_size) {
2663 * place the seqnum in the packet so that the main process
2664 * can reply with signing
2666 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2667 smb_ss_field, seqnum);
2668 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2669 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2672 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2673 smbd_echo_activate_writer(state);
2676 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2677 int parent_pipe)
2679 struct smbd_echo_state *state;
2681 state = talloc_zero(sconn, struct smbd_echo_state);
2682 if (state == NULL) {
2683 DEBUG(1, ("talloc failed\n"));
2684 return;
2686 state->sconn = sconn;
2687 state->parent_pipe = parent_pipe;
2688 state->ev = s3_tevent_context_init(state);
2689 if (state->ev == NULL) {
2690 DEBUG(1, ("tevent_context_init failed\n"));
2691 TALLOC_FREE(state);
2692 return;
2694 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2695 TEVENT_FD_READ, smbd_echo_exit,
2696 state);
2697 if (state->parent_fde == NULL) {
2698 DEBUG(1, ("tevent_add_fd failed\n"));
2699 TALLOC_FREE(state);
2700 return;
2702 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2703 TEVENT_FD_READ, smbd_echo_reader,
2704 state);
2705 if (state->read_fde == NULL) {
2706 DEBUG(1, ("tevent_add_fd failed\n"));
2707 TALLOC_FREE(state);
2708 return;
2711 while (true) {
2712 if (tevent_loop_once(state->ev) == -1) {
2713 DEBUG(1, ("tevent_loop_once failed: %s\n",
2714 strerror(errno)));
2715 break;
2718 TALLOC_FREE(state);
2722 * Handle SMBecho requests in a forked child process
2724 bool fork_echo_handler(struct smbd_server_connection *sconn)
2726 int listener_pipe[2];
2727 int res;
2728 pid_t child;
2730 res = pipe(listener_pipe);
2731 if (res == -1) {
2732 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2733 return false;
2735 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2736 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2737 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2738 goto fail;
2741 child = sys_fork();
2742 if (child == 0) {
2743 NTSTATUS status;
2745 close(listener_pipe[0]);
2746 set_blocking(listener_pipe[1], false);
2748 status = reinit_after_fork(sconn->msg_ctx,
2749 server_event_context(),
2750 procid_self(), false);
2751 if (!NT_STATUS_IS_OK(status)) {
2752 DEBUG(1, ("reinit_after_fork failed: %s\n",
2753 nt_errstr(status)));
2754 exit(1);
2756 smbd_echo_loop(sconn, listener_pipe[1]);
2757 exit(0);
2759 close(listener_pipe[1]);
2760 listener_pipe[1] = -1;
2761 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2763 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2766 * Without smb signing this is the same as the normal smbd
2767 * listener. This needs to change once signing comes in.
2769 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2770 sconn,
2771 sconn->smb1.echo_handler.trusted_fd,
2772 EVENT_FD_READ,
2773 smbd_server_echo_handler,
2774 sconn);
2775 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2776 DEBUG(1, ("event_add_fd failed\n"));
2777 goto fail;
2780 return true;
2782 fail:
2783 if (listener_pipe[0] != -1) {
2784 close(listener_pipe[0]);
2786 if (listener_pipe[1] != -1) {
2787 close(listener_pipe[1]);
2789 sconn->smb1.echo_handler.trusted_fd = -1;
2790 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2791 close(sconn->smb1.echo_handler.socket_lock_fd);
2793 sconn->smb1.echo_handler.trusted_fd = -1;
2794 sconn->smb1.echo_handler.socket_lock_fd = -1;
2795 return false;
2798 #if CLUSTER_SUPPORT
2800 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2801 struct sockaddr_storage *srv,
2802 struct sockaddr_storage *clnt)
2804 struct ctdbd_connection *cconn;
2805 char tmp_addr[INET6_ADDRSTRLEN];
2806 char *addr;
2808 cconn = messaging_ctdbd_connection();
2809 if (cconn == NULL) {
2810 return NT_STATUS_NO_MEMORY;
2813 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2814 addr = talloc_strdup(cconn, tmp_addr);
2815 if (addr == NULL) {
2816 return NT_STATUS_NO_MEMORY;
2818 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2821 #endif
2823 /****************************************************************************
2824 Process commands from the client
2825 ****************************************************************************/
2827 void smbd_process(struct smbd_server_connection *sconn)
2829 TALLOC_CTX *frame = talloc_stackframe();
2830 struct sockaddr_storage ss;
2831 struct sockaddr *sa = NULL;
2832 socklen_t sa_socklen;
2833 struct tsocket_address *local_address = NULL;
2834 struct tsocket_address *remote_address = NULL;
2835 const char *remaddr = NULL;
2836 char *rhost;
2837 int ret;
2839 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2841 * We're not making the decision here,
2842 * we're just allowing the client
2843 * to decide between SMB1 and SMB2
2844 * with the first negprot
2845 * packet.
2847 sconn->using_smb2 = true;
2850 /* Ensure child is set to blocking mode */
2851 set_blocking(sconn->sock,True);
2853 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2854 set_socket_options(sconn->sock, lp_socket_options());
2856 sa = (struct sockaddr *)(void *)&ss;
2857 sa_socklen = sizeof(ss);
2858 ret = getpeername(sconn->sock, sa, &sa_socklen);
2859 if (ret != 0) {
2860 int level = (errno == ENOTCONN)?2:0;
2861 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2862 exit_server_cleanly("getpeername() failed.\n");
2864 ret = tsocket_address_bsd_from_sockaddr(sconn,
2865 sa, sa_socklen,
2866 &remote_address);
2867 if (ret != 0) {
2868 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2869 __location__, strerror(errno)));
2870 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2873 sa = (struct sockaddr *)(void *)&ss;
2874 sa_socklen = sizeof(ss);
2875 ret = getsockname(sconn->sock, sa, &sa_socklen);
2876 if (ret != 0) {
2877 int level = (errno == ENOTCONN)?2:0;
2878 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2879 exit_server_cleanly("getsockname() failed.\n");
2881 ret = tsocket_address_bsd_from_sockaddr(sconn,
2882 sa, sa_socklen,
2883 &local_address);
2884 if (ret != 0) {
2885 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2886 __location__, strerror(errno)));
2887 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2890 sconn->local_address = local_address;
2891 sconn->remote_address = remote_address;
2893 if (tsocket_address_is_inet(remote_address, "ip")) {
2894 remaddr = tsocket_address_inet_addr_string(
2895 sconn->remote_address,
2896 talloc_tos());
2897 if (remaddr == NULL) {
2898 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
2899 __location__, strerror(errno)));
2900 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
2902 } else {
2903 remaddr = "0.0.0.0";
2906 /* this is needed so that we get decent entries
2907 in smbstatus for port 445 connects */
2908 set_remote_machine_name(remaddr, false);
2909 reload_services(sconn->msg_ctx, sconn->sock, true);
2912 * Before the first packet, check the global hosts allow/ hosts deny
2913 * parameters before doing any parsing of packets passed to us by the
2914 * client. This prevents attacks on our parsing code from hosts not in
2915 * the hosts allow list.
2918 ret = get_remote_hostname(remote_address,
2919 &rhost,
2920 talloc_tos());
2921 if (ret < 0) {
2922 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
2923 __location__, strerror(errno)));
2924 exit_server_cleanly("get_remote_hostname failed.\n");
2926 if (strequal(rhost, "UNKNOWN")) {
2927 rhost = talloc_strdup(talloc_tos(), remaddr);
2929 sconn->remote_hostname = talloc_move(sconn, &rhost);
2931 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2932 sconn->remote_hostname,
2933 remaddr)) {
2935 * send a negative session response "not listening on calling
2936 * name"
2938 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2939 DEBUG( 1, ("Connection denied from %s to %s\n",
2940 tsocket_address_string(remote_address, talloc_tos()),
2941 tsocket_address_string(local_address, talloc_tos())));
2942 (void)srv_send_smb(sconn,(char *)buf, false,
2943 0, false, NULL);
2944 exit_server_cleanly("connection denied");
2947 DEBUG(10, ("Connection allowed from %s to %s\n",
2948 tsocket_address_string(remote_address, talloc_tos()),
2949 tsocket_address_string(local_address, talloc_tos())));
2951 init_modules();
2953 smb_perfcount_init();
2955 if (!init_account_policy()) {
2956 exit_server("Could not open account policy tdb.\n");
2959 if (*lp_rootdir()) {
2960 if (chroot(lp_rootdir()) != 0) {
2961 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2962 exit_server("Failed to chroot()");
2964 if (chdir("/") == -1) {
2965 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2966 exit_server("Failed to chroot()");
2968 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2971 if (!srv_init_signing(sconn)) {
2972 exit_server("Failed to init smb_signing");
2975 /* Setup oplocks */
2976 if (!init_oplocks(sconn->msg_ctx))
2977 exit_server("Failed to init oplocks");
2979 /* register our message handlers */
2980 messaging_register(sconn->msg_ctx, NULL,
2981 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2982 messaging_register(sconn->msg_ctx, NULL,
2983 MSG_SMB_CLOSE_FILE, msg_close_file);
2986 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2987 * MSGs to all child processes
2989 messaging_deregister(sconn->msg_ctx,
2990 MSG_DEBUG, NULL);
2991 messaging_register(sconn->msg_ctx, NULL,
2992 MSG_DEBUG, debug_message);
2994 if ((lp_keepalive() != 0)
2995 && !(event_add_idle(server_event_context(), NULL,
2996 timeval_set(lp_keepalive(), 0),
2997 "keepalive", keepalive_fn,
2998 NULL))) {
2999 DEBUG(0, ("Could not add keepalive event\n"));
3000 exit(1);
3003 if (!(event_add_idle(server_event_context(), NULL,
3004 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3005 "deadtime", deadtime_fn, sconn))) {
3006 DEBUG(0, ("Could not add deadtime event\n"));
3007 exit(1);
3010 if (!(event_add_idle(server_event_context(), NULL,
3011 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3012 "housekeeping", housekeeping_fn, sconn))) {
3013 DEBUG(0, ("Could not add housekeeping event\n"));
3014 exit(1);
3017 #ifdef CLUSTER_SUPPORT
3019 if (lp_clustering()) {
3021 * We need to tell ctdb about our client's TCP
3022 * connection, so that for failover ctdbd can send
3023 * tickle acks, triggering a reconnection by the
3024 * client.
3027 struct sockaddr_storage srv, clnt;
3029 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3030 NTSTATUS status;
3031 status = smbd_register_ips(sconn, &srv, &clnt);
3032 if (!NT_STATUS_IS_OK(status)) {
3033 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3034 nt_errstr(status)));
3036 } else
3038 DEBUG(0,("Unable to get tcp info for "
3039 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3040 strerror(errno)));
3044 #endif
3046 sconn->nbt.got_session = false;
3048 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3050 sconn->smb1.sessions.done_sesssetup = false;
3051 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3052 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3053 /* users from session setup */
3054 sconn->smb1.sessions.session_userlist = NULL;
3055 /* workgroup from session setup. */
3056 sconn->smb1.sessions.session_workgroup = NULL;
3057 /* this holds info on user ids that are already validated for this VC */
3058 sconn->smb1.sessions.validated_users = NULL;
3059 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3060 sconn->smb1.sessions.num_validated_vuids = 0;
3062 conn_init(sconn);
3063 if (!init_dptrs(sconn)) {
3064 exit_server("init_dptrs() failed");
3067 sconn->smb1.fde = event_add_fd(server_event_context(),
3068 sconn,
3069 sconn->sock,
3070 EVENT_FD_READ,
3071 smbd_server_connection_handler,
3072 sconn);
3073 if (!sconn->smb1.fde) {
3074 exit_server("failed to create smbd_server_connection fde");
3077 TALLOC_FREE(frame);
3079 while (True) {
3080 NTSTATUS status;
3082 frame = talloc_stackframe_pool(8192);
3084 errno = 0;
3086 status = smbd_server_connection_loop_once(sconn);
3087 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3088 !NT_STATUS_IS_OK(status)) {
3089 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3090 " exiting\n", nt_errstr(status)));
3091 break;
3094 TALLOC_FREE(frame);
3097 exit_server_cleanly(NULL);
3100 bool req_is_in_chain(struct smb_request *req)
3102 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3104 * We're right now handling a subsequent request, so we must
3105 * be in a chain
3107 return true;
3110 if (!is_andx_req(req->cmd)) {
3111 return false;
3114 if (req->wct < 2) {
3116 * Okay, an illegal request, but definitely not chained :-)
3118 return false;
3121 return (CVAL(req->vwv+0, 0) != 0xFF);