param: Rename variable used for lp_netbios_scope szNetbiosScope
[Samba.git] / source3 / smbd / process.c
blob1f4cfe7e65f6e29366be5ce08040ae39546e1d05
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/queue_process.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"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
44 /* Internal message queue for deferred opens. */
45 struct pending_message_list {
46 struct pending_message_list *next, *prev;
47 struct timeval request_time; /* When was this first issued? */
48 struct smbd_server_connection *sconn;
49 struct tevent_timer *te;
50 struct smb_perfcount_data pcd;
51 uint32_t seqnum;
52 bool encrypted;
53 bool processed;
54 DATA_BLOB buf;
55 DATA_BLOB private_data;
58 static void construct_reply_common(struct smb_request *req, const char *inbuf,
59 char *outbuf);
60 static struct pending_message_list *get_deferred_open_message_smb(
61 struct smbd_server_connection *sconn, uint64_t mid);
62 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
66 bool ok;
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 return true;
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
75 return true;
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
83 F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
86 if (!ok) {
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 return false;
91 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
93 return true;
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
105 bool ok;
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 return true;
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
114 return true;
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
120 F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
123 if (!ok) {
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 return false;
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
130 return true;
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
143 Send an smb to a fd.
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
151 size_t len = 0;
152 ssize_t ret;
153 char *buf_out = buffer;
155 smbd_lock_socket(sconn);
157 if (do_signing) {
158 /* Sign the outgoing packet if required. */
159 srv_calculate_sign_mac(sconn, buf_out, seqnum);
162 if (do_encrypt) {
163 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
164 if (!NT_STATUS_IS_OK(status)) {
165 DEBUG(0, ("send_smb: SMB encryption failed "
166 "on outgoing packet! Error %s\n",
167 nt_errstr(status) ));
168 ret = -1;
169 goto out;
173 len = smb_len_large(buf_out) + 4;
175 ret = write_data(sconn->sock, buf_out, len);
176 if (ret <= 0) {
178 char addr[INET6_ADDRSTRLEN];
180 * Try and give an error message saying what
181 * client failed.
183 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
184 (int)getpid(), (int)len,
185 get_peer_addr(sconn->sock, addr, sizeof(addr)),
186 (int)ret, strerror(errno) ));
188 srv_free_enc_buffer(sconn, buf_out);
189 goto out;
192 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
193 srv_free_enc_buffer(sconn, buf_out);
194 out:
195 SMB_PERFCOUNT_END(pcd);
197 smbd_unlock_socket(sconn);
198 return (ret > 0);
201 /*******************************************************************
202 Setup the word count and byte count for a smb message.
203 ********************************************************************/
205 int srv_set_message(char *buf,
206 int num_words,
207 int num_bytes,
208 bool zero)
210 if (zero && (num_words || num_bytes)) {
211 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
213 SCVAL(buf,smb_wct,num_words);
214 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
215 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
216 return (smb_size + num_words*2 + num_bytes);
219 static bool valid_smb_header(struct smbd_server_connection *sconn,
220 const uint8_t *inbuf)
222 if (is_encrypted_packet(sconn, inbuf)) {
223 return true;
226 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
227 * but it just looks weird to call strncmp for this one.
229 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
232 /* Socket functions for smbd packet processing. */
234 static bool valid_packet_size(size_t len)
237 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
238 * of header. Don't print the error if this fits.... JRA.
241 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
242 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
243 (unsigned long)len));
244 return false;
246 return true;
249 static NTSTATUS read_packet_remainder(int fd, char *buffer,
250 unsigned int timeout, ssize_t len)
252 NTSTATUS status;
254 if (len <= 0) {
255 return NT_STATUS_OK;
258 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
259 if (!NT_STATUS_IS_OK(status)) {
260 char addr[INET6_ADDRSTRLEN];
261 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
262 "error = %s.\n",
263 get_peer_addr(fd, addr, sizeof(addr)),
264 nt_errstr(status)));
266 return status;
269 /****************************************************************************
270 Attempt a zerocopy writeX read. We know here that len > smb_size-4
271 ****************************************************************************/
274 * Unfortunately, earlier versions of smbclient/libsmbclient
275 * don't send this "standard" writeX header. I've fixed this
276 * for 3.2 but we'll use the old method with earlier versions.
277 * Windows and CIFSFS at least use this standard size. Not
278 * sure about MacOSX.
281 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
282 (2*14) + /* word count (including bcc) */ \
283 1 /* pad byte */)
285 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
286 const char lenbuf[4],
287 struct smbd_server_connection *sconn,
288 int sock,
289 char **buffer,
290 unsigned int timeout,
291 size_t *p_unread,
292 size_t *len_ret)
294 /* Size of a WRITEX call (+4 byte len). */
295 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
296 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
297 ssize_t toread;
298 NTSTATUS status;
300 memcpy(writeX_header, lenbuf, 4);
302 status = read_fd_with_timeout(
303 sock, writeX_header + 4,
304 STANDARD_WRITE_AND_X_HEADER_SIZE,
305 STANDARD_WRITE_AND_X_HEADER_SIZE,
306 timeout, NULL);
308 if (!NT_STATUS_IS_OK(status)) {
309 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
310 "error = %s.\n",
311 tsocket_address_string(sconn->remote_address,
312 talloc_tos()),
313 nt_errstr(status)));
314 return status;
318 * Ok - now try and see if this is a possible
319 * valid writeX call.
322 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
324 * If the data offset is beyond what
325 * we've read, drain the extra bytes.
327 uint16_t doff = SVAL(writeX_header,smb_vwv11);
328 ssize_t newlen;
330 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
331 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
332 if (drain_socket(sock, drain) != drain) {
333 smb_panic("receive_smb_raw_talloc_partial_read:"
334 " failed to drain pending bytes");
336 } else {
337 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
340 /* Spoof down the length and null out the bcc. */
341 set_message_bcc(writeX_header, 0);
342 newlen = smb_len(writeX_header);
344 /* Copy the header we've written. */
346 *buffer = (char *)talloc_memdup(mem_ctx,
347 writeX_header,
348 sizeof(writeX_header));
350 if (*buffer == NULL) {
351 DEBUG(0, ("Could not allocate inbuf of length %d\n",
352 (int)sizeof(writeX_header)));
353 return NT_STATUS_NO_MEMORY;
356 /* Work out the remaining bytes. */
357 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
358 *len_ret = newlen + 4;
359 return NT_STATUS_OK;
362 if (!valid_packet_size(len)) {
363 return NT_STATUS_INVALID_PARAMETER;
367 * Not a valid writeX call. Just do the standard
368 * talloc and return.
371 *buffer = talloc_array(mem_ctx, char, len+4);
373 if (*buffer == NULL) {
374 DEBUG(0, ("Could not allocate inbuf of length %d\n",
375 (int)len+4));
376 return NT_STATUS_NO_MEMORY;
379 /* Copy in what we already read. */
380 memcpy(*buffer,
381 writeX_header,
382 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
383 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
385 if(toread > 0) {
386 status = read_packet_remainder(
387 sock,
388 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
389 timeout, toread);
391 if (!NT_STATUS_IS_OK(status)) {
392 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
393 nt_errstr(status)));
394 return status;
398 *len_ret = len + 4;
399 return NT_STATUS_OK;
402 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
403 struct smbd_server_connection *sconn,
404 int sock,
405 char **buffer, unsigned int timeout,
406 size_t *p_unread, size_t *plen)
408 char lenbuf[4];
409 size_t len;
410 int min_recv_size = lp_min_receive_file_size();
411 NTSTATUS status;
413 *p_unread = 0;
415 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
416 &len);
417 if (!NT_STATUS_IS_OK(status)) {
418 return status;
421 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
422 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
423 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
424 !srv_is_signing_active(sconn) &&
425 sconn->smb1.echo_handler.trusted_fde == NULL) {
427 return receive_smb_raw_talloc_partial_read(
428 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
429 p_unread, plen);
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * The +4 here can't wrap, we've checked the length above already.
440 *buffer = talloc_array(mem_ctx, char, len+4);
442 if (*buffer == NULL) {
443 DEBUG(0, ("Could not allocate inbuf of length %d\n",
444 (int)len+4));
445 return NT_STATUS_NO_MEMORY;
448 memcpy(*buffer, lenbuf, sizeof(lenbuf));
450 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
451 if (!NT_STATUS_IS_OK(status)) {
452 return status;
455 *plen = len + 4;
456 return NT_STATUS_OK;
459 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
460 struct smbd_server_connection *sconn,
461 int sock,
462 char **buffer, unsigned int timeout,
463 size_t *p_unread, bool *p_encrypted,
464 size_t *p_len,
465 uint32_t *seqnum,
466 bool trusted_channel)
468 size_t len = 0;
469 NTSTATUS status;
471 *p_encrypted = false;
473 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
474 p_unread, &len);
475 if (!NT_STATUS_IS_OK(status)) {
476 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
477 ("receive_smb_raw_talloc failed for client %s "
478 "read error = %s.\n",
479 tsocket_address_string(sconn->remote_address,
480 talloc_tos()),
481 nt_errstr(status)) );
482 return status;
485 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
486 status = srv_decrypt_buffer(sconn, *buffer);
487 if (!NT_STATUS_IS_OK(status)) {
488 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
489 "incoming packet! Error %s\n",
490 nt_errstr(status) ));
491 return status;
493 *p_encrypted = true;
496 /* Check the incoming SMB signature. */
497 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
498 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
499 "incoming packet!\n"));
500 return NT_STATUS_INVALID_NETWORK_RESPONSE;
503 *p_len = len;
504 return NT_STATUS_OK;
508 * Initialize a struct smb_request from an inbuf
511 static bool init_smb_request(struct smb_request *req,
512 struct smbd_server_connection *sconn,
513 const uint8 *inbuf,
514 size_t unread_bytes, bool encrypted,
515 uint32_t seqnum)
517 struct smbXsrv_tcon *tcon;
518 NTSTATUS status;
519 NTTIME now;
520 size_t req_size = smb_len(inbuf) + 4;
522 /* Ensure we have at least smb_size bytes. */
523 if (req_size < smb_size) {
524 DEBUG(0,("init_smb_request: invalid request size %u\n",
525 (unsigned int)req_size ));
526 return false;
529 req->request_time = timeval_current();
530 now = timeval_to_nttime(&req->request_time);
532 req->cmd = CVAL(inbuf, smb_com);
533 req->flags2 = SVAL(inbuf, smb_flg2);
534 req->smbpid = SVAL(inbuf, smb_pid);
535 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
536 req->seqnum = seqnum;
537 req->vuid = SVAL(inbuf, smb_uid);
538 req->tid = SVAL(inbuf, smb_tid);
539 req->wct = CVAL(inbuf, smb_wct);
540 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
541 req->buflen = smb_buflen(inbuf);
542 req->buf = (const uint8_t *)smb_buf_const(inbuf);
543 req->unread_bytes = unread_bytes;
544 req->encrypted = encrypted;
545 req->sconn = sconn;
546 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
547 if (NT_STATUS_IS_OK(status)) {
548 req->conn = tcon->compat;
549 } else {
550 req->conn = NULL;
552 req->chain_fsp = NULL;
553 req->smb2req = NULL;
554 req->priv_paths = NULL;
555 req->chain = NULL;
556 smb_init_perfcount_data(&req->pcd);
558 /* Ensure we have at least wct words and 2 bytes of bcc. */
559 if (smb_size + req->wct*2 > req_size) {
560 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
561 (unsigned int)req->wct,
562 (unsigned int)req_size));
563 return false;
565 /* Ensure bcc is correct. */
566 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
567 DEBUG(0,("init_smb_request: invalid bcc number %u "
568 "(wct = %u, size %u)\n",
569 (unsigned int)req->buflen,
570 (unsigned int)req->wct,
571 (unsigned int)req_size));
572 return false;
575 req->outbuf = NULL;
576 return true;
579 static void process_smb(struct smbd_server_connection *conn,
580 uint8_t *inbuf, size_t nread, size_t unread_bytes,
581 uint32_t seqnum, bool encrypted,
582 struct smb_perfcount_data *deferred_pcd);
584 static void smbd_deferred_open_timer(struct tevent_context *ev,
585 struct tevent_timer *te,
586 struct timeval _tval,
587 void *private_data)
589 struct pending_message_list *msg = talloc_get_type(private_data,
590 struct pending_message_list);
591 struct smbd_server_connection *sconn = msg->sconn;
592 TALLOC_CTX *mem_ctx = talloc_tos();
593 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
594 uint8_t *inbuf;
596 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
597 msg->buf.length);
598 if (inbuf == NULL) {
599 exit_server("smbd_deferred_open_timer: talloc failed\n");
600 return;
603 /* We leave this message on the queue so the open code can
604 know this is a retry. */
605 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
606 (unsigned long long)mid ));
608 /* Mark the message as processed so this is not
609 * re-processed in error. */
610 msg->processed = true;
612 process_smb(sconn, inbuf,
613 msg->buf.length, 0,
614 msg->seqnum, msg->encrypted, &msg->pcd);
616 /* If it's still there and was processed, remove it. */
617 msg = get_deferred_open_message_smb(sconn, mid);
618 if (msg && msg->processed) {
619 remove_deferred_open_message_smb(sconn, mid);
623 /****************************************************************************
624 Function to push a message onto the tail of a linked list of smb messages ready
625 for processing.
626 ****************************************************************************/
628 static bool push_queued_message(struct smb_request *req,
629 struct timeval request_time,
630 struct timeval end_time,
631 char *private_data, size_t private_len)
633 int msg_len = smb_len(req->inbuf) + 4;
634 struct pending_message_list *msg;
636 msg = talloc_zero(NULL, struct pending_message_list);
638 if(msg == NULL) {
639 DEBUG(0,("push_message: malloc fail (1)\n"));
640 return False;
642 msg->sconn = req->sconn;
644 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
645 if(msg->buf.data == NULL) {
646 DEBUG(0,("push_message: malloc fail (2)\n"));
647 TALLOC_FREE(msg);
648 return False;
651 msg->request_time = request_time;
652 msg->seqnum = req->seqnum;
653 msg->encrypted = req->encrypted;
654 msg->processed = false;
655 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
657 if (private_data) {
658 msg->private_data = data_blob_talloc(msg, private_data,
659 private_len);
660 if (msg->private_data.data == NULL) {
661 DEBUG(0,("push_message: malloc fail (3)\n"));
662 TALLOC_FREE(msg);
663 return False;
667 #if 0
668 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
669 msg,
670 end_time,
671 smbd_deferred_open_timer,
672 msg);
673 if (!msg->te) {
674 DEBUG(0,("push_message: event_add_timed failed\n"));
675 TALLOC_FREE(msg);
676 return false;
678 #endif
680 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
681 struct pending_message_list *);
683 DEBUG(10,("push_message: pushed message length %u on "
684 "deferred_open_queue\n", (unsigned int)msg_len));
686 return True;
689 /****************************************************************************
690 Function to delete a sharing violation open message by mid.
691 ****************************************************************************/
693 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
694 uint64_t mid)
696 struct pending_message_list *pml;
698 if (sconn->using_smb2) {
699 remove_deferred_open_message_smb2(sconn, mid);
700 return;
703 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
704 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
705 DEBUG(10,("remove_deferred_open_message_smb: "
706 "deleting mid %llu len %u\n",
707 (unsigned long long)mid,
708 (unsigned int)pml->buf.length ));
709 DLIST_REMOVE(sconn->deferred_open_queue, pml);
710 TALLOC_FREE(pml);
711 return;
716 /****************************************************************************
717 Move a sharing violation open retry message to the front of the list and
718 schedule it for immediate processing.
719 ****************************************************************************/
721 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
722 uint64_t mid)
724 struct pending_message_list *pml;
725 int i = 0;
727 if (sconn->using_smb2) {
728 return schedule_deferred_open_message_smb2(sconn, mid);
731 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
732 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
734 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
735 "msg_mid = %llu\n",
736 i++,
737 (unsigned long long)msg_mid ));
739 if (mid == msg_mid) {
740 struct tevent_timer *te;
742 if (pml->processed) {
743 /* A processed message should not be
744 * rescheduled. */
745 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
746 "message mid %llu was already processed\n",
747 (unsigned long long)msg_mid ));
748 continue;
751 DEBUG(10,("schedule_deferred_open_message_smb: "
752 "scheduling mid %llu\n",
753 (unsigned long long)mid ));
755 te = tevent_add_timer(pml->sconn->ev_ctx,
756 pml,
757 timeval_zero(),
758 smbd_deferred_open_timer,
759 pml);
760 if (!te) {
761 DEBUG(10,("schedule_deferred_open_message_smb: "
762 "event_add_timed() failed, "
763 "skipping mid %llu\n",
764 (unsigned long long)msg_mid ));
767 TALLOC_FREE(pml->te);
768 pml->te = te;
769 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
770 return true;
774 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
775 "find message mid %llu\n",
776 (unsigned long long)mid ));
778 return false;
781 /****************************************************************************
782 Return true if this mid is on the deferred queue and was not yet processed.
783 ****************************************************************************/
785 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
787 struct pending_message_list *pml;
789 if (sconn->using_smb2) {
790 return open_was_deferred_smb2(sconn, mid);
793 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
794 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
795 return True;
798 return False;
801 /****************************************************************************
802 Return the message queued by this mid.
803 ****************************************************************************/
805 static struct pending_message_list *get_deferred_open_message_smb(
806 struct smbd_server_connection *sconn, uint64_t mid)
808 struct pending_message_list *pml;
810 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
811 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
812 return pml;
815 return NULL;
818 /****************************************************************************
819 Get the state data queued by this mid.
820 ****************************************************************************/
822 bool get_deferred_open_message_state(struct smb_request *smbreq,
823 struct timeval *p_request_time,
824 void **pp_state)
826 struct pending_message_list *pml;
828 if (smbreq->sconn->using_smb2) {
829 return get_deferred_open_message_state_smb2(smbreq->smb2req,
830 p_request_time,
831 pp_state);
834 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
835 if (!pml) {
836 return false;
838 if (p_request_time) {
839 *p_request_time = pml->request_time;
841 if (pp_state) {
842 *pp_state = (void *)pml->private_data.data;
844 return true;
847 /****************************************************************************
848 Function to push a deferred open smb message onto a linked list of local smb
849 messages ready for processing.
850 ****************************************************************************/
852 bool push_deferred_open_message_smb(struct smb_request *req,
853 struct timeval request_time,
854 struct timeval timeout,
855 struct file_id id,
856 char *private_data, size_t priv_len)
858 struct timeval end_time;
860 if (req->smb2req) {
861 return push_deferred_open_message_smb2(req->smb2req,
862 request_time,
863 timeout,
865 private_data,
866 priv_len);
869 if (req->unread_bytes) {
870 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
871 "unread_bytes = %u\n",
872 (unsigned int)req->unread_bytes ));
873 smb_panic("push_deferred_open_message_smb: "
874 "logic error unread_bytes != 0" );
877 end_time = timeval_sum(&request_time, &timeout);
879 DEBUG(10,("push_deferred_open_message_smb: pushing message "
880 "len %u mid %llu timeout time [%u.%06u]\n",
881 (unsigned int) smb_len(req->inbuf)+4,
882 (unsigned long long)req->mid,
883 (unsigned int)end_time.tv_sec,
884 (unsigned int)end_time.tv_usec));
886 return push_queued_message(req, request_time, end_time,
887 private_data, priv_len);
890 static void smbd_sig_term_handler(struct tevent_context *ev,
891 struct tevent_signal *se,
892 int signum,
893 int count,
894 void *siginfo,
895 void *private_data)
897 exit_server_cleanly("termination signal");
900 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
902 struct tevent_signal *se;
904 se = tevent_add_signal(sconn->ev_ctx,
905 sconn,
906 SIGTERM, 0,
907 smbd_sig_term_handler,
908 sconn);
909 if (!se) {
910 exit_server("failed to setup SIGTERM handler");
914 static void smbd_sig_hup_handler(struct tevent_context *ev,
915 struct tevent_signal *se,
916 int signum,
917 int count,
918 void *siginfo,
919 void *private_data)
921 struct smbd_server_connection *sconn =
922 talloc_get_type_abort(private_data,
923 struct smbd_server_connection);
925 change_to_root_user();
926 DEBUG(1,("Reloading services after SIGHUP\n"));
927 reload_services(sconn, conn_snum_used, false);
930 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
932 struct tevent_signal *se;
934 se = tevent_add_signal(sconn->ev_ctx,
935 sconn,
936 SIGHUP, 0,
937 smbd_sig_hup_handler,
938 sconn);
939 if (!se) {
940 exit_server("failed to setup SIGHUP handler");
944 static void smbd_conf_updated(struct messaging_context *msg,
945 void *private_data,
946 uint32_t msg_type,
947 struct server_id server_id,
948 DATA_BLOB *data)
950 struct smbd_server_connection *sconn =
951 talloc_get_type_abort(private_data,
952 struct smbd_server_connection);
954 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
955 "updated. Reloading.\n"));
956 change_to_root_user();
957 reload_services(sconn, conn_snum_used, false);
961 * Only allow 5 outstanding trans requests. We're allocating memory, so
962 * prevent a DoS.
965 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
967 int count = 0;
968 for (; list != NULL; list = list->next) {
970 if (list->mid == mid) {
971 return NT_STATUS_INVALID_PARAMETER;
974 count += 1;
976 if (count > 5) {
977 return NT_STATUS_INSUFFICIENT_RESOURCES;
980 return NT_STATUS_OK;
984 These flags determine some of the permissions required to do an operation
986 Note that I don't set NEED_WRITE on some write operations because they
987 are used by some brain-dead clients when printing, and I don't want to
988 force write permissions on print services.
990 #define AS_USER (1<<0)
991 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
992 #define TIME_INIT (1<<2)
993 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
994 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
995 #define DO_CHDIR (1<<6)
998 define a list of possible SMB messages and their corresponding
999 functions. Any message that has a NULL function is unimplemented -
1000 please feel free to contribute implementations!
1002 static const struct smb_message_struct {
1003 const char *name;
1004 void (*fn)(struct smb_request *req);
1005 int flags;
1006 } smb_messages[256] = {
1008 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1009 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1010 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1011 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1012 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1013 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1014 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1015 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1016 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1017 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1018 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1019 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1020 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1021 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1022 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1023 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1024 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1025 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1026 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1027 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1028 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1029 /* 0x15 */ { NULL, NULL, 0 },
1030 /* 0x16 */ { NULL, NULL, 0 },
1031 /* 0x17 */ { NULL, NULL, 0 },
1032 /* 0x18 */ { NULL, NULL, 0 },
1033 /* 0x19 */ { NULL, NULL, 0 },
1034 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1035 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1036 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1037 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1038 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1039 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1040 /* 0x20 */ { "SMBwritec", NULL,0},
1041 /* 0x21 */ { NULL, NULL, 0 },
1042 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1043 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1044 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1045 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1046 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1047 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1048 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1049 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1050 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1051 /* 0x2b */ { "SMBecho",reply_echo,0},
1052 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1053 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1054 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1055 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1056 /* 0x30 */ { NULL, NULL, 0 },
1057 /* 0x31 */ { NULL, NULL, 0 },
1058 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1059 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1060 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1061 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1062 /* 0x36 */ { NULL, NULL, 0 },
1063 /* 0x37 */ { NULL, NULL, 0 },
1064 /* 0x38 */ { NULL, NULL, 0 },
1065 /* 0x39 */ { NULL, NULL, 0 },
1066 /* 0x3a */ { NULL, NULL, 0 },
1067 /* 0x3b */ { NULL, NULL, 0 },
1068 /* 0x3c */ { NULL, NULL, 0 },
1069 /* 0x3d */ { NULL, NULL, 0 },
1070 /* 0x3e */ { NULL, NULL, 0 },
1071 /* 0x3f */ { NULL, NULL, 0 },
1072 /* 0x40 */ { NULL, NULL, 0 },
1073 /* 0x41 */ { NULL, NULL, 0 },
1074 /* 0x42 */ { NULL, NULL, 0 },
1075 /* 0x43 */ { NULL, NULL, 0 },
1076 /* 0x44 */ { NULL, NULL, 0 },
1077 /* 0x45 */ { NULL, NULL, 0 },
1078 /* 0x46 */ { NULL, NULL, 0 },
1079 /* 0x47 */ { NULL, NULL, 0 },
1080 /* 0x48 */ { NULL, NULL, 0 },
1081 /* 0x49 */ { NULL, NULL, 0 },
1082 /* 0x4a */ { NULL, NULL, 0 },
1083 /* 0x4b */ { NULL, NULL, 0 },
1084 /* 0x4c */ { NULL, NULL, 0 },
1085 /* 0x4d */ { NULL, NULL, 0 },
1086 /* 0x4e */ { NULL, NULL, 0 },
1087 /* 0x4f */ { NULL, NULL, 0 },
1088 /* 0x50 */ { NULL, NULL, 0 },
1089 /* 0x51 */ { NULL, NULL, 0 },
1090 /* 0x52 */ { NULL, NULL, 0 },
1091 /* 0x53 */ { NULL, NULL, 0 },
1092 /* 0x54 */ { NULL, NULL, 0 },
1093 /* 0x55 */ { NULL, NULL, 0 },
1094 /* 0x56 */ { NULL, NULL, 0 },
1095 /* 0x57 */ { NULL, NULL, 0 },
1096 /* 0x58 */ { NULL, NULL, 0 },
1097 /* 0x59 */ { NULL, NULL, 0 },
1098 /* 0x5a */ { NULL, NULL, 0 },
1099 /* 0x5b */ { NULL, NULL, 0 },
1100 /* 0x5c */ { NULL, NULL, 0 },
1101 /* 0x5d */ { NULL, NULL, 0 },
1102 /* 0x5e */ { NULL, NULL, 0 },
1103 /* 0x5f */ { NULL, NULL, 0 },
1104 /* 0x60 */ { NULL, NULL, 0 },
1105 /* 0x61 */ { NULL, NULL, 0 },
1106 /* 0x62 */ { NULL, NULL, 0 },
1107 /* 0x63 */ { NULL, NULL, 0 },
1108 /* 0x64 */ { NULL, NULL, 0 },
1109 /* 0x65 */ { NULL, NULL, 0 },
1110 /* 0x66 */ { NULL, NULL, 0 },
1111 /* 0x67 */ { NULL, NULL, 0 },
1112 /* 0x68 */ { NULL, NULL, 0 },
1113 /* 0x69 */ { NULL, NULL, 0 },
1114 /* 0x6a */ { NULL, NULL, 0 },
1115 /* 0x6b */ { NULL, NULL, 0 },
1116 /* 0x6c */ { NULL, NULL, 0 },
1117 /* 0x6d */ { NULL, NULL, 0 },
1118 /* 0x6e */ { NULL, NULL, 0 },
1119 /* 0x6f */ { NULL, NULL, 0 },
1120 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1121 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1122 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1123 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1124 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1125 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1126 /* 0x76 */ { NULL, NULL, 0 },
1127 /* 0x77 */ { NULL, NULL, 0 },
1128 /* 0x78 */ { NULL, NULL, 0 },
1129 /* 0x79 */ { NULL, NULL, 0 },
1130 /* 0x7a */ { NULL, NULL, 0 },
1131 /* 0x7b */ { NULL, NULL, 0 },
1132 /* 0x7c */ { NULL, NULL, 0 },
1133 /* 0x7d */ { NULL, NULL, 0 },
1134 /* 0x7e */ { NULL, NULL, 0 },
1135 /* 0x7f */ { NULL, NULL, 0 },
1136 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1137 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1138 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1139 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1140 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1141 /* 0x85 */ { NULL, NULL, 0 },
1142 /* 0x86 */ { NULL, NULL, 0 },
1143 /* 0x87 */ { NULL, NULL, 0 },
1144 /* 0x88 */ { NULL, NULL, 0 },
1145 /* 0x89 */ { NULL, NULL, 0 },
1146 /* 0x8a */ { NULL, NULL, 0 },
1147 /* 0x8b */ { NULL, NULL, 0 },
1148 /* 0x8c */ { NULL, NULL, 0 },
1149 /* 0x8d */ { NULL, NULL, 0 },
1150 /* 0x8e */ { NULL, NULL, 0 },
1151 /* 0x8f */ { NULL, NULL, 0 },
1152 /* 0x90 */ { NULL, NULL, 0 },
1153 /* 0x91 */ { NULL, NULL, 0 },
1154 /* 0x92 */ { NULL, NULL, 0 },
1155 /* 0x93 */ { NULL, NULL, 0 },
1156 /* 0x94 */ { NULL, NULL, 0 },
1157 /* 0x95 */ { NULL, NULL, 0 },
1158 /* 0x96 */ { NULL, NULL, 0 },
1159 /* 0x97 */ { NULL, NULL, 0 },
1160 /* 0x98 */ { NULL, NULL, 0 },
1161 /* 0x99 */ { NULL, NULL, 0 },
1162 /* 0x9a */ { NULL, NULL, 0 },
1163 /* 0x9b */ { NULL, NULL, 0 },
1164 /* 0x9c */ { NULL, NULL, 0 },
1165 /* 0x9d */ { NULL, NULL, 0 },
1166 /* 0x9e */ { NULL, NULL, 0 },
1167 /* 0x9f */ { NULL, NULL, 0 },
1168 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1169 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1170 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1171 /* 0xa3 */ { NULL, NULL, 0 },
1172 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1173 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1174 /* 0xa6 */ { NULL, NULL, 0 },
1175 /* 0xa7 */ { NULL, NULL, 0 },
1176 /* 0xa8 */ { NULL, NULL, 0 },
1177 /* 0xa9 */ { NULL, NULL, 0 },
1178 /* 0xaa */ { NULL, NULL, 0 },
1179 /* 0xab */ { NULL, NULL, 0 },
1180 /* 0xac */ { NULL, NULL, 0 },
1181 /* 0xad */ { NULL, NULL, 0 },
1182 /* 0xae */ { NULL, NULL, 0 },
1183 /* 0xaf */ { NULL, NULL, 0 },
1184 /* 0xb0 */ { NULL, NULL, 0 },
1185 /* 0xb1 */ { NULL, NULL, 0 },
1186 /* 0xb2 */ { NULL, NULL, 0 },
1187 /* 0xb3 */ { NULL, NULL, 0 },
1188 /* 0xb4 */ { NULL, NULL, 0 },
1189 /* 0xb5 */ { NULL, NULL, 0 },
1190 /* 0xb6 */ { NULL, NULL, 0 },
1191 /* 0xb7 */ { NULL, NULL, 0 },
1192 /* 0xb8 */ { NULL, NULL, 0 },
1193 /* 0xb9 */ { NULL, NULL, 0 },
1194 /* 0xba */ { NULL, NULL, 0 },
1195 /* 0xbb */ { NULL, NULL, 0 },
1196 /* 0xbc */ { NULL, NULL, 0 },
1197 /* 0xbd */ { NULL, NULL, 0 },
1198 /* 0xbe */ { NULL, NULL, 0 },
1199 /* 0xbf */ { NULL, NULL, 0 },
1200 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1201 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1202 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1203 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1204 /* 0xc4 */ { NULL, NULL, 0 },
1205 /* 0xc5 */ { NULL, NULL, 0 },
1206 /* 0xc6 */ { NULL, NULL, 0 },
1207 /* 0xc7 */ { NULL, NULL, 0 },
1208 /* 0xc8 */ { NULL, NULL, 0 },
1209 /* 0xc9 */ { NULL, NULL, 0 },
1210 /* 0xca */ { NULL, NULL, 0 },
1211 /* 0xcb */ { NULL, NULL, 0 },
1212 /* 0xcc */ { NULL, NULL, 0 },
1213 /* 0xcd */ { NULL, NULL, 0 },
1214 /* 0xce */ { NULL, NULL, 0 },
1215 /* 0xcf */ { NULL, NULL, 0 },
1216 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1217 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1218 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1219 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1220 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1221 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1222 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1223 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1224 /* 0xd8 */ { NULL, NULL, 0 },
1225 /* 0xd9 */ { NULL, NULL, 0 },
1226 /* 0xda */ { NULL, NULL, 0 },
1227 /* 0xdb */ { NULL, NULL, 0 },
1228 /* 0xdc */ { NULL, NULL, 0 },
1229 /* 0xdd */ { NULL, NULL, 0 },
1230 /* 0xde */ { NULL, NULL, 0 },
1231 /* 0xdf */ { NULL, NULL, 0 },
1232 /* 0xe0 */ { NULL, NULL, 0 },
1233 /* 0xe1 */ { NULL, NULL, 0 },
1234 /* 0xe2 */ { NULL, NULL, 0 },
1235 /* 0xe3 */ { NULL, NULL, 0 },
1236 /* 0xe4 */ { NULL, NULL, 0 },
1237 /* 0xe5 */ { NULL, NULL, 0 },
1238 /* 0xe6 */ { NULL, NULL, 0 },
1239 /* 0xe7 */ { NULL, NULL, 0 },
1240 /* 0xe8 */ { NULL, NULL, 0 },
1241 /* 0xe9 */ { NULL, NULL, 0 },
1242 /* 0xea */ { NULL, NULL, 0 },
1243 /* 0xeb */ { NULL, NULL, 0 },
1244 /* 0xec */ { NULL, NULL, 0 },
1245 /* 0xed */ { NULL, NULL, 0 },
1246 /* 0xee */ { NULL, NULL, 0 },
1247 /* 0xef */ { NULL, NULL, 0 },
1248 /* 0xf0 */ { NULL, NULL, 0 },
1249 /* 0xf1 */ { NULL, NULL, 0 },
1250 /* 0xf2 */ { NULL, NULL, 0 },
1251 /* 0xf3 */ { NULL, NULL, 0 },
1252 /* 0xf4 */ { NULL, NULL, 0 },
1253 /* 0xf5 */ { NULL, NULL, 0 },
1254 /* 0xf6 */ { NULL, NULL, 0 },
1255 /* 0xf7 */ { NULL, NULL, 0 },
1256 /* 0xf8 */ { NULL, NULL, 0 },
1257 /* 0xf9 */ { NULL, NULL, 0 },
1258 /* 0xfa */ { NULL, NULL, 0 },
1259 /* 0xfb */ { NULL, NULL, 0 },
1260 /* 0xfc */ { NULL, NULL, 0 },
1261 /* 0xfd */ { NULL, NULL, 0 },
1262 /* 0xfe */ { NULL, NULL, 0 },
1263 /* 0xff */ { NULL, NULL, 0 }
1267 /*******************************************************************
1268 allocate and initialize a reply packet
1269 ********************************************************************/
1271 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1272 const char *inbuf, char **outbuf, uint8_t num_words,
1273 uint32_t num_bytes)
1275 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1278 * Protect against integer wrap.
1279 * The SMB layer reply can be up to 0xFFFFFF bytes.
1281 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1282 char *msg;
1283 if (asprintf(&msg, "num_bytes too large: %u",
1284 (unsigned)num_bytes) == -1) {
1285 msg = discard_const_p(char, "num_bytes too large");
1287 smb_panic(msg);
1291 * Here we include the NBT header for now.
1293 *outbuf = talloc_array(mem_ctx, char,
1294 NBT_HDR_SIZE + smb_len);
1295 if (*outbuf == NULL) {
1296 return false;
1299 construct_reply_common(req, inbuf, *outbuf);
1300 srv_set_message(*outbuf, num_words, num_bytes, false);
1302 * Zero out the word area, the caller has to take care of the bcc area
1303 * himself
1305 if (num_words != 0) {
1306 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1309 return true;
1312 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1314 char *outbuf;
1315 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1316 num_bytes)) {
1317 smb_panic("could not allocate output buffer\n");
1319 req->outbuf = (uint8_t *)outbuf;
1323 /*******************************************************************
1324 Dump a packet to a file.
1325 ********************************************************************/
1327 static void smb_dump(const char *name, int type, const char *data)
1329 size_t len;
1330 int fd, i;
1331 char *fname = NULL;
1332 if (DEBUGLEVEL < 50) {
1333 return;
1336 len = smb_len_tcp(data)+4;
1337 for (i=1;i<100;i++) {
1338 fname = talloc_asprintf(talloc_tos(),
1339 "/tmp/%s.%d.%s",
1340 name,
1342 type ? "req" : "resp");
1343 if (fname == NULL) {
1344 return;
1346 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1347 if (fd != -1 || errno != EEXIST) break;
1348 TALLOC_FREE(fname);
1350 if (fd != -1) {
1351 ssize_t ret = write(fd, data, len);
1352 if (ret != len)
1353 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1354 close(fd);
1355 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1357 TALLOC_FREE(fname);
1360 /****************************************************************************
1361 Prepare everything for calling the actual request function, and potentially
1362 call the request function via the "new" interface.
1364 Return False if the "legacy" function needs to be called, everything is
1365 prepared.
1367 Return True if we're done.
1369 I know this API sucks, but it is the one with the least code change I could
1370 find.
1371 ****************************************************************************/
1373 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1375 int flags;
1376 uint64_t session_tag;
1377 connection_struct *conn = NULL;
1378 struct smbd_server_connection *sconn = req->sconn;
1379 NTTIME now = timeval_to_nttime(&req->request_time);
1380 struct smbXsrv_session *session = NULL;
1381 NTSTATUS status;
1383 errno = 0;
1385 if (smb_messages[type].fn == NULL) {
1386 DEBUG(0,("Unknown message type %d!\n",type));
1387 smb_dump("Unknown", 1, (const char *)req->inbuf);
1388 reply_unknown_new(req, type);
1389 return NULL;
1392 flags = smb_messages[type].flags;
1394 /* In share mode security we must ignore the vuid. */
1395 session_tag = req->vuid;
1396 conn = req->conn;
1398 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1399 (int)getpid(), (unsigned long)conn));
1401 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1403 /* Ensure this value is replaced in the incoming packet. */
1404 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1407 * Ensure the correct username is in current_user_info. This is a
1408 * really ugly bugfix for problems with multiple session_setup_and_X's
1409 * being done and allowing %U and %G substitutions to work correctly.
1410 * There is a reason this code is done here, don't move it unless you
1411 * know what you're doing... :-).
1412 * JRA.
1416 * lookup an existing session
1418 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1419 * here, the main check is still in change_to_user()
1421 status = smb1srv_session_lookup(sconn->conn,
1422 session_tag,
1423 now,
1424 &session);
1425 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1426 switch (type) {
1427 case SMBsesssetupX:
1428 status = NT_STATUS_OK;
1429 break;
1430 default:
1431 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1432 (unsigned long long)session_tag,
1433 (unsigned long long)req->mid));
1434 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1435 return conn;
1439 if (session_tag != sconn->conn->last_session_id) {
1440 struct user_struct *vuser = NULL;
1442 sconn->conn->last_session_id = session_tag;
1443 if (session) {
1444 vuser = session->compat;
1446 if (vuser) {
1447 set_current_user_info(
1448 vuser->session_info->unix_info->sanitized_username,
1449 vuser->session_info->unix_info->unix_name,
1450 vuser->session_info->info->domain_name);
1454 /* Does this call need to be run as the connected user? */
1455 if (flags & AS_USER) {
1457 /* Does this call need a valid tree connection? */
1458 if (!conn) {
1460 * Amazingly, the error code depends on the command
1461 * (from Samba4).
1463 if (type == SMBntcreateX) {
1464 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1465 } else {
1466 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1468 return NULL;
1471 if (!change_to_user(conn,session_tag)) {
1472 DEBUG(0, ("Error: Could not change to user. Removing "
1473 "deferred open, mid=%llu.\n",
1474 (unsigned long long)req->mid));
1475 reply_force_doserror(req, ERRSRV, ERRbaduid);
1476 return conn;
1479 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1481 /* Does it need write permission? */
1482 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1483 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1484 return conn;
1487 /* IPC services are limited */
1488 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1489 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1490 return conn;
1492 } else {
1493 /* This call needs to be run as root */
1494 change_to_root_user();
1497 /* load service specific parameters */
1498 if (conn) {
1499 if (req->encrypted) {
1500 conn->encrypted_tid = true;
1501 /* encrypted required from now on. */
1502 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1503 } else if (ENCRYPTION_REQUIRED(conn)) {
1504 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1505 DEBUG(1,("service[%s] requires encryption"
1506 "%s ACCESS_DENIED. mid=%llu\n",
1507 lp_servicename(talloc_tos(), SNUM(conn)),
1508 smb_fn_name(type),
1509 (unsigned long long)req->mid));
1510 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1511 return conn;
1515 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1516 (flags & (AS_USER|DO_CHDIR)
1517 ?True:False))) {
1518 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1519 return conn;
1521 conn->num_smb_operations++;
1525 * Does this protocol need to be run as guest? (Only archane
1526 * messenger service requests have this...)
1528 if (flags & AS_GUEST) {
1529 char *raddr;
1530 bool ok;
1532 if (!change_to_guest()) {
1533 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1534 return conn;
1537 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1538 talloc_tos());
1539 if (raddr == NULL) {
1540 reply_nterror(req, NT_STATUS_NO_MEMORY);
1541 return conn;
1545 * Haven't we checked this in smbd_process already???
1548 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1549 sconn->remote_hostname, raddr);
1550 TALLOC_FREE(raddr);
1552 if (!ok) {
1553 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1554 return conn;
1558 smb_messages[type].fn(req);
1559 return req->conn;
1562 /****************************************************************************
1563 Construct a reply to the incoming packet.
1564 ****************************************************************************/
1566 static void construct_reply(struct smbd_server_connection *sconn,
1567 char *inbuf, int size, size_t unread_bytes,
1568 uint32_t seqnum, bool encrypted,
1569 struct smb_perfcount_data *deferred_pcd)
1571 connection_struct *conn;
1572 struct smb_request *req;
1574 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1575 smb_panic("could not allocate smb_request");
1578 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1579 encrypted, seqnum)) {
1580 exit_server_cleanly("Invalid SMB request");
1583 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1585 /* we popped this message off the queue - keep original perf data */
1586 if (deferred_pcd)
1587 req->pcd = *deferred_pcd;
1588 else {
1589 SMB_PERFCOUNT_START(&req->pcd);
1590 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1591 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1594 conn = switch_message(req->cmd, req);
1596 if (req->outbuf == NULL) {
1597 return;
1600 if (CVAL(req->outbuf,0) == 0) {
1601 show_msg((char *)req->outbuf);
1604 if (!srv_send_smb(req->sconn,
1605 (char *)req->outbuf,
1606 true, req->seqnum+1,
1607 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1608 &req->pcd)) {
1609 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1612 TALLOC_FREE(req);
1614 return;
1617 static void construct_reply_chain(struct smbd_server_connection *sconn,
1618 char *inbuf, int size, uint32_t seqnum,
1619 bool encrypted,
1620 struct smb_perfcount_data *deferred_pcd)
1622 struct smb_request **reqs = NULL;
1623 struct smb_request *req;
1624 unsigned num_reqs;
1625 bool ok;
1627 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1628 seqnum, &reqs, &num_reqs);
1629 if (!ok) {
1630 char errbuf[smb_size];
1631 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1632 __LINE__, __FILE__);
1633 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1634 NULL)) {
1635 exit_server_cleanly("construct_reply_chain: "
1636 "srv_send_smb failed.");
1638 return;
1641 req = reqs[0];
1642 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1644 req->conn = switch_message(req->cmd, req);
1646 if (req->outbuf == NULL) {
1648 * Request has suspended itself, will come
1649 * back here.
1651 return;
1653 smb_request_done(req);
1657 * To be called from an async SMB handler that is potentially chained
1658 * when it is finished for shipping.
1661 void smb_request_done(struct smb_request *req)
1663 struct smb_request **reqs = NULL;
1664 struct smb_request *first_req;
1665 size_t i, num_reqs, next_index;
1666 NTSTATUS status;
1668 if (req->chain == NULL) {
1669 first_req = req;
1670 goto shipit;
1673 reqs = req->chain;
1674 num_reqs = talloc_array_length(reqs);
1676 for (i=0; i<num_reqs; i++) {
1677 if (reqs[i] == req) {
1678 break;
1681 if (i == num_reqs) {
1683 * Invalid chain, should not happen
1685 status = NT_STATUS_INTERNAL_ERROR;
1686 goto error;
1688 next_index = i+1;
1690 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1691 struct smb_request *next = reqs[next_index];
1692 struct smbXsrv_tcon *tcon;
1693 NTTIME now = timeval_to_nttime(&req->request_time);
1695 next->vuid = SVAL(req->outbuf, smb_uid);
1696 next->tid = SVAL(req->outbuf, smb_tid);
1697 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1698 now, &tcon);
1699 if (NT_STATUS_IS_OK(status)) {
1700 req->conn = tcon->compat;
1701 } else {
1702 req->conn = NULL;
1704 next->chain_fsp = req->chain_fsp;
1705 next->inbuf = req->inbuf;
1707 req = next;
1708 req->conn = switch_message(req->cmd, req);
1710 if (req->outbuf == NULL) {
1712 * Request has suspended itself, will come
1713 * back here.
1715 return;
1717 next_index += 1;
1720 first_req = reqs[0];
1722 for (i=1; i<next_index; i++) {
1723 bool ok;
1725 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1726 if (!ok) {
1727 status = NT_STATUS_INTERNAL_ERROR;
1728 goto error;
1732 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1733 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1736 * This scary statement intends to set the
1737 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1738 * to the value last_req->outbuf carries
1740 SSVAL(first_req->outbuf, smb_flg2,
1741 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1742 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1745 * Transfer the error codes from the subrequest to the main one
1747 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1748 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1750 _smb_setlen_large(
1751 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1753 shipit:
1754 if (!srv_send_smb(first_req->sconn,
1755 (char *)first_req->outbuf,
1756 true, first_req->seqnum+1,
1757 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1758 &first_req->pcd)) {
1759 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1760 "failed.");
1762 TALLOC_FREE(req); /* non-chained case */
1763 TALLOC_FREE(reqs); /* chained case */
1764 return;
1766 error:
1768 char errbuf[smb_size];
1769 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1770 if (!srv_send_smb(req->sconn, errbuf, true,
1771 req->seqnum+1, req->encrypted,
1772 NULL)) {
1773 exit_server_cleanly("construct_reply_chain: "
1774 "srv_send_smb failed.");
1777 TALLOC_FREE(req); /* non-chained case */
1778 TALLOC_FREE(reqs); /* chained case */
1781 /****************************************************************************
1782 Process an smb from the client
1783 ****************************************************************************/
1784 static void process_smb(struct smbd_server_connection *sconn,
1785 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1786 uint32_t seqnum, bool encrypted,
1787 struct smb_perfcount_data *deferred_pcd)
1789 int msg_type = CVAL(inbuf,0);
1791 DO_PROFILE_INC(smb_count);
1793 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1794 smb_len(inbuf) ) );
1795 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1796 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1798 if (msg_type != NBSSmessage) {
1800 * NetBIOS session request, keepalive, etc.
1802 reply_special(sconn, (char *)inbuf, nread);
1803 goto done;
1806 if (sconn->using_smb2) {
1807 /* At this point we're not really using smb2,
1808 * we make the decision here.. */
1809 if (smbd_is_smb2_header(inbuf, nread)) {
1810 smbd_smb2_first_negprot(sconn, inbuf, nread);
1811 return;
1812 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1813 && CVAL(inbuf, smb_com) != 0x72) {
1814 /* This is a non-negprot SMB1 packet.
1815 Disable SMB2 from now on. */
1816 sconn->using_smb2 = false;
1820 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1821 * so subtract 4 from it. */
1822 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1823 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1824 smb_len(inbuf)));
1826 /* special magic for immediate exit */
1827 if ((nread == 9) &&
1828 (IVAL(inbuf, 4) == 0x74697865) &&
1829 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1830 uint8_t exitcode = CVAL(inbuf, 8);
1831 DEBUG(1, ("Exiting immediately with code %d\n",
1832 (int)exitcode));
1833 exit(exitcode);
1836 exit_server_cleanly("Non-SMB packet");
1839 show_msg((char *)inbuf);
1841 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1842 construct_reply_chain(sconn, (char *)inbuf, nread,
1843 seqnum, encrypted, deferred_pcd);
1844 } else {
1845 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1846 seqnum, encrypted, deferred_pcd);
1849 sconn->trans_num++;
1851 done:
1852 sconn->num_requests++;
1854 /* The timeout_processing function isn't run nearly
1855 often enough to implement 'max log size' without
1856 overrunning the size of the file by many megabytes.
1857 This is especially true if we are running at debug
1858 level 10. Checking every 50 SMBs is a nice
1859 tradeoff of performance vs log file size overrun. */
1861 if ((sconn->num_requests % 50) == 0 &&
1862 need_to_check_log_size()) {
1863 change_to_root_user();
1864 check_log_size();
1868 /****************************************************************************
1869 Return a string containing the function name of a SMB command.
1870 ****************************************************************************/
1872 const char *smb_fn_name(int type)
1874 const char *unknown_name = "SMBunknown";
1876 if (smb_messages[type].name == NULL)
1877 return(unknown_name);
1879 return(smb_messages[type].name);
1882 /****************************************************************************
1883 Helper functions for contruct_reply.
1884 ****************************************************************************/
1886 void add_to_common_flags2(uint32 v)
1888 common_flags2 |= v;
1891 void remove_from_common_flags2(uint32 v)
1893 common_flags2 &= ~v;
1896 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1897 char *outbuf)
1899 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1900 uint16_t out_flags2 = common_flags2;
1902 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1903 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1904 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1906 srv_set_message(outbuf,0,0,false);
1908 SCVAL(outbuf, smb_com, req->cmd);
1909 SIVAL(outbuf,smb_rcls,0);
1910 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1911 SSVAL(outbuf,smb_flg2, out_flags2);
1912 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1913 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1915 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1916 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1917 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1918 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1921 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1923 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1927 * @brief Find the smb_cmd offset of the last command pushed
1928 * @param[in] buf The buffer we're building up
1929 * @retval Where can we put our next andx cmd?
1931 * While chaining requests, the "next" request we're looking at needs to put
1932 * its SMB_Command before the data the previous request already built up added
1933 * to the chain. Find the offset to the place where we have to put our cmd.
1936 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1938 uint8_t cmd;
1939 size_t ofs;
1941 cmd = CVAL(buf, smb_com);
1943 if (!is_andx_req(cmd)) {
1944 return false;
1947 ofs = smb_vwv0;
1949 while (CVAL(buf, ofs) != 0xff) {
1951 if (!is_andx_req(CVAL(buf, ofs))) {
1952 return false;
1956 * ofs is from start of smb header, so add the 4 length
1957 * bytes. The next cmd is right after the wct field.
1959 ofs = SVAL(buf, ofs+2) + 4 + 1;
1961 if (ofs+4 >= talloc_get_size(buf)) {
1962 return false;
1966 *pofs = ofs;
1967 return true;
1971 * @brief Do the smb chaining at a buffer level
1972 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1973 * @param[in] andx_buf Buffer to be appended
1976 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1978 uint8_t smb_command = CVAL(andx_buf, smb_com);
1979 uint8_t wct = CVAL(andx_buf, smb_wct);
1980 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1981 uint32_t num_bytes = smb_buflen(andx_buf);
1982 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1984 uint8_t *outbuf;
1985 size_t old_size, new_size;
1986 size_t ofs;
1987 size_t chain_padding = 0;
1988 size_t andx_cmd_ofs;
1991 old_size = talloc_get_size(*poutbuf);
1993 if ((old_size % 4) != 0) {
1995 * Align the wct field of subsequent requests to a 4-byte
1996 * boundary
1998 chain_padding = 4 - (old_size % 4);
2002 * After the old request comes the new wct field (1 byte), the vwv's
2003 * and the num_bytes field.
2006 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2007 new_size += num_bytes;
2009 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2010 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2011 (unsigned)new_size));
2012 return false;
2015 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2016 if (outbuf == NULL) {
2017 DEBUG(0, ("talloc failed\n"));
2018 return false;
2020 *poutbuf = outbuf;
2022 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2023 DEBUG(1, ("invalid command chain\n"));
2024 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2025 return false;
2028 if (chain_padding != 0) {
2029 memset(outbuf + old_size, 0, chain_padding);
2030 old_size += chain_padding;
2033 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2034 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2036 ofs = old_size;
2039 * Push the chained request:
2041 * wct field
2044 SCVAL(outbuf, ofs, wct);
2045 ofs += 1;
2048 * vwv array
2051 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2054 * HACK ALERT
2056 * Read&X has an offset into its data buffer at
2057 * vwv[6]. reply_read_andx has no idea anymore that it's
2058 * running from within a chain, so we have to fix up the
2059 * offset here.
2061 * Although it looks disgusting at this place, I want to keep
2062 * it here. The alternative would be to push knowledge about
2063 * the andx chain down into read&x again.
2066 if (smb_command == SMBreadX) {
2067 uint8_t *bytes_addr;
2069 if (wct < 7) {
2071 * Invalid read&x response
2073 return false;
2076 bytes_addr = outbuf + ofs /* vwv start */
2077 + sizeof(uint16_t) * wct /* vwv array */
2078 + sizeof(uint16_t); /* bcc */
2080 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2081 bytes_addr - outbuf - 4);
2084 ofs += sizeof(uint16_t) * wct;
2087 * bcc (byte count)
2090 SSVAL(outbuf, ofs, num_bytes);
2091 ofs += sizeof(uint16_t);
2094 * The bytes field
2097 memcpy(outbuf + ofs, bytes, num_bytes);
2099 return true;
2102 bool smb1_is_chain(const uint8_t *buf)
2104 uint8_t cmd, wct, andx_cmd;
2106 cmd = CVAL(buf, smb_com);
2107 if (!is_andx_req(cmd)) {
2108 return false;
2110 wct = CVAL(buf, smb_wct);
2111 if (wct < 2) {
2112 return false;
2114 andx_cmd = CVAL(buf, smb_vwv);
2115 return (andx_cmd != 0xFF);
2118 bool smb1_walk_chain(const uint8_t *buf,
2119 bool (*fn)(uint8_t cmd,
2120 uint8_t wct, const uint16_t *vwv,
2121 uint16_t num_bytes, const uint8_t *bytes,
2122 void *private_data),
2123 void *private_data)
2125 size_t smblen = smb_len(buf);
2126 const char *smb_buf = smb_base(buf);
2127 uint8_t cmd, chain_cmd;
2128 uint8_t wct;
2129 const uint16_t *vwv;
2130 uint16_t num_bytes;
2131 const uint8_t *bytes;
2133 cmd = CVAL(buf, smb_com);
2134 wct = CVAL(buf, smb_wct);
2135 vwv = (const uint16_t *)(buf + smb_vwv);
2136 num_bytes = smb_buflen(buf);
2137 bytes = (const uint8_t *)smb_buf_const(buf);
2139 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2140 return false;
2143 if (!is_andx_req(cmd)) {
2144 return true;
2146 if (wct < 2) {
2147 return false;
2150 chain_cmd = CVAL(vwv, 0);
2152 while (chain_cmd != 0xff) {
2153 uint32_t chain_offset; /* uint32_t to avoid overflow */
2154 size_t length_needed;
2155 ptrdiff_t vwv_offset;
2157 chain_offset = SVAL(vwv+1, 0);
2160 * Check if the client tries to fool us. The chain
2161 * offset needs to point beyond the current request in
2162 * the chain, it needs to strictly grow. Otherwise we
2163 * might be tricked into an endless loop always
2164 * processing the same request over and over again. We
2165 * used to assume that vwv and the byte buffer array
2166 * in a chain are always attached, but OS/2 the
2167 * Write&X/Read&X chain puts the Read&X vwv array
2168 * right behind the Write&X vwv chain. The Write&X bcc
2169 * array is put behind the Read&X vwv array. So now we
2170 * check whether the chain offset points strictly
2171 * behind the previous vwv array. req->buf points
2172 * right after the vwv array of the previous
2173 * request. See
2174 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2175 * more information.
2178 vwv_offset = ((const char *)vwv - smb_buf);
2179 if (chain_offset <= vwv_offset) {
2180 return false;
2184 * Next check: Make sure the chain offset does not
2185 * point beyond the overall smb request length.
2188 length_needed = chain_offset+1; /* wct */
2189 if (length_needed > smblen) {
2190 return false;
2194 * Now comes the pointer magic. Goal here is to set up
2195 * vwv and buf correctly again. The chain offset (the
2196 * former vwv[1]) points at the new wct field.
2199 wct = CVAL(smb_buf, chain_offset);
2201 if (is_andx_req(chain_cmd) && (wct < 2)) {
2202 return false;
2206 * Next consistency check: Make the new vwv array fits
2207 * in the overall smb request.
2210 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2211 if (length_needed > smblen) {
2212 return false;
2214 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2217 * Now grab the new byte buffer....
2220 num_bytes = SVAL(vwv+wct, 0);
2223 * .. and check that it fits.
2226 length_needed += num_bytes;
2227 if (length_needed > smblen) {
2228 return false;
2230 bytes = (const uint8_t *)(vwv+wct+1);
2232 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2233 return false;
2236 if (!is_andx_req(chain_cmd)) {
2237 return true;
2239 chain_cmd = CVAL(vwv, 0);
2241 return true;
2244 static bool smb1_chain_length_cb(uint8_t cmd,
2245 uint8_t wct, const uint16_t *vwv,
2246 uint16_t num_bytes, const uint8_t *bytes,
2247 void *private_data)
2249 unsigned *count = (unsigned *)private_data;
2250 *count += 1;
2251 return true;
2254 unsigned smb1_chain_length(const uint8_t *buf)
2256 unsigned count = 0;
2258 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2259 return 0;
2261 return count;
2264 struct smb1_parse_chain_state {
2265 TALLOC_CTX *mem_ctx;
2266 const uint8_t *buf;
2267 struct smbd_server_connection *sconn;
2268 bool encrypted;
2269 uint32_t seqnum;
2271 struct smb_request **reqs;
2272 unsigned num_reqs;
2275 static bool smb1_parse_chain_cb(uint8_t cmd,
2276 uint8_t wct, const uint16_t *vwv,
2277 uint16_t num_bytes, const uint8_t *bytes,
2278 void *private_data)
2280 struct smb1_parse_chain_state *state =
2281 (struct smb1_parse_chain_state *)private_data;
2282 struct smb_request **reqs;
2283 struct smb_request *req;
2284 bool ok;
2286 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2287 struct smb_request *, state->num_reqs+1);
2288 if (reqs == NULL) {
2289 return false;
2291 state->reqs = reqs;
2293 req = talloc(reqs, struct smb_request);
2294 if (req == NULL) {
2295 return false;
2298 ok = init_smb_request(req, state->sconn, state->buf, 0,
2299 state->encrypted, state->seqnum);
2300 if (!ok) {
2301 return false;
2303 req->cmd = cmd;
2304 req->wct = wct;
2305 req->vwv = vwv;
2306 req->buflen = num_bytes;
2307 req->buf = bytes;
2309 reqs[state->num_reqs] = req;
2310 state->num_reqs += 1;
2311 return true;
2314 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2315 struct smbd_server_connection *sconn,
2316 bool encrypted, uint32_t seqnum,
2317 struct smb_request ***reqs, unsigned *num_reqs)
2319 struct smb1_parse_chain_state state;
2320 unsigned i;
2322 state.mem_ctx = mem_ctx;
2323 state.buf = buf;
2324 state.sconn = sconn;
2325 state.encrypted = encrypted;
2326 state.seqnum = seqnum;
2327 state.reqs = NULL;
2328 state.num_reqs = 0;
2330 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2331 TALLOC_FREE(state.reqs);
2332 return false;
2334 for (i=0; i<state.num_reqs; i++) {
2335 state.reqs[i]->chain = state.reqs;
2337 *reqs = state.reqs;
2338 *num_reqs = state.num_reqs;
2339 return true;
2342 /****************************************************************************
2343 Check if services need reloading.
2344 ****************************************************************************/
2346 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2349 if (last_smb_conf_reload_time == 0) {
2350 last_smb_conf_reload_time = t;
2353 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2354 reload_services(sconn, conn_snum_used, true);
2355 last_smb_conf_reload_time = t;
2359 static bool fd_is_readable(int fd)
2361 int ret, revents;
2363 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2365 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2369 static void smbd_server_connection_write_handler(
2370 struct smbd_server_connection *sconn)
2372 /* TODO: make write nonblocking */
2375 static void smbd_server_connection_read_handler(
2376 struct smbd_server_connection *sconn, int fd)
2378 uint8_t *inbuf = NULL;
2379 size_t inbuf_len = 0;
2380 size_t unread_bytes = 0;
2381 bool encrypted = false;
2382 TALLOC_CTX *mem_ctx = talloc_tos();
2383 NTSTATUS status;
2384 uint32_t seqnum;
2386 bool async_echo = lp_async_smb_echo_handler();
2387 bool from_client = false;
2389 if (async_echo) {
2390 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2392 * This is the super-ugly hack to prefer the packets
2393 * forwarded by the echo handler over the ones by the
2394 * client directly
2396 fd = sconn->smb1.echo_handler.trusted_fd;
2400 from_client = (sconn->sock == fd);
2402 if (async_echo && from_client) {
2403 smbd_lock_socket(sconn);
2405 if (!fd_is_readable(fd)) {
2406 DEBUG(10,("the echo listener was faster\n"));
2407 smbd_unlock_socket(sconn);
2408 return;
2412 /* TODO: make this completely nonblocking */
2413 status = receive_smb_talloc(mem_ctx, sconn, fd,
2414 (char **)(void *)&inbuf,
2415 0, /* timeout */
2416 &unread_bytes,
2417 &encrypted,
2418 &inbuf_len, &seqnum,
2419 !from_client /* trusted channel */);
2421 if (async_echo && from_client) {
2422 smbd_unlock_socket(sconn);
2425 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2426 goto process;
2428 if (NT_STATUS_IS_ERR(status)) {
2429 exit_server_cleanly("failed to receive smb request");
2431 if (!NT_STATUS_IS_OK(status)) {
2432 return;
2435 process:
2436 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2437 seqnum, encrypted, NULL);
2440 static void smbd_server_connection_handler(struct tevent_context *ev,
2441 struct tevent_fd *fde,
2442 uint16_t flags,
2443 void *private_data)
2445 struct smbd_server_connection *conn = talloc_get_type(private_data,
2446 struct smbd_server_connection);
2448 if (flags & TEVENT_FD_WRITE) {
2449 smbd_server_connection_write_handler(conn);
2450 return;
2452 if (flags & TEVENT_FD_READ) {
2453 smbd_server_connection_read_handler(conn, conn->sock);
2454 return;
2458 static void smbd_server_echo_handler(struct tevent_context *ev,
2459 struct tevent_fd *fde,
2460 uint16_t flags,
2461 void *private_data)
2463 struct smbd_server_connection *conn = talloc_get_type(private_data,
2464 struct smbd_server_connection);
2466 if (flags & TEVENT_FD_WRITE) {
2467 smbd_server_connection_write_handler(conn);
2468 return;
2470 if (flags & TEVENT_FD_READ) {
2471 smbd_server_connection_read_handler(
2472 conn, conn->smb1.echo_handler.trusted_fd);
2473 return;
2477 #ifdef CLUSTER_SUPPORT
2479 struct smbd_release_ip_state {
2480 struct smbd_server_connection *sconn;
2481 char addr[INET6_ADDRSTRLEN];
2484 /****************************************************************************
2485 received when we should release a specific IP
2486 ****************************************************************************/
2487 static void release_ip(const char *ip, void *priv)
2489 struct smbd_release_ip_state *state =
2490 talloc_get_type_abort(priv,
2491 struct smbd_release_ip_state);
2492 const char *addr = state->addr;
2493 const char *p = addr;
2495 if (strncmp("::ffff:", addr, 7) == 0) {
2496 p = addr + 7;
2499 DEBUG(10, ("Got release IP message for %s, "
2500 "our address is %s\n", ip, p));
2502 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2503 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2504 ip));
2506 * With SMB2 we should do a clean disconnect,
2507 * the previous_session_id in the session setup
2508 * will cleanup the old session, tcons and opens.
2510 * A clean disconnect is needed in order to support
2511 * durable handles.
2513 * Note: typically this is never triggered
2514 * as we got a TCP RST (triggered by ctdb event scripts)
2515 * before we get CTDB_SRVID_RELEASE_IP.
2517 * We used to call _exit(1) here, but as this was mostly never
2518 * triggered and has implication on our process model,
2519 * we can just use smbd_server_connection_terminate()
2520 * (also for SMB1).
2522 smbd_server_connection_terminate(state->sconn,
2523 "CTDB_SRVID_RELEASE_IP");
2524 return;
2528 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2529 struct sockaddr_storage *srv,
2530 struct sockaddr_storage *clnt)
2532 struct smbd_release_ip_state *state;
2533 struct ctdbd_connection *cconn;
2535 cconn = messaging_ctdbd_connection();
2536 if (cconn == NULL) {
2537 return NT_STATUS_NO_MEMORY;
2540 state = talloc_zero(sconn, struct smbd_release_ip_state);
2541 if (state == NULL) {
2542 return NT_STATUS_NO_MEMORY;
2544 state->sconn = sconn;
2545 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2546 return NT_STATUS_NO_MEMORY;
2549 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2552 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2553 struct sockaddr_storage *client)
2555 socklen_t length;
2556 length = sizeof(*server);
2557 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2558 return -1;
2560 length = sizeof(*client);
2561 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2562 return -1;
2564 return 0;
2566 #endif
2568 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2569 void *private_data, uint32_t msg_type,
2570 struct server_id server_id, DATA_BLOB *data)
2572 struct smbd_server_connection *sconn = talloc_get_type_abort(
2573 private_data, struct smbd_server_connection);
2574 const char *ip = (char *) data->data;
2575 char *client_ip;
2577 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2579 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2580 talloc_tos());
2581 if (client_ip == NULL) {
2582 return;
2585 if (strequal(ip, client_ip)) {
2586 DEBUG(1, ("Got kill client message for %s - "
2587 "exiting immediately\n", ip));
2588 exit_server_cleanly("Forced disconnect for client");
2591 TALLOC_FREE(client_ip);
2595 * Send keepalive packets to our client
2597 static bool keepalive_fn(const struct timeval *now, void *private_data)
2599 struct smbd_server_connection *sconn = talloc_get_type_abort(
2600 private_data, struct smbd_server_connection);
2601 bool ret;
2603 if (sconn->using_smb2) {
2604 /* Don't do keepalives on an SMB2 connection. */
2605 return false;
2608 smbd_lock_socket(sconn);
2609 ret = send_keepalive(sconn->sock);
2610 smbd_unlock_socket(sconn);
2612 if (!ret) {
2613 char addr[INET6_ADDRSTRLEN];
2615 * Try and give an error message saying what
2616 * client failed.
2618 DEBUG(0, ("send_keepalive failed for client %s. "
2619 "Error %s - exiting\n",
2620 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2621 strerror(errno)));
2622 return False;
2624 return True;
2628 * Do the recurring check if we're idle
2630 static bool deadtime_fn(const struct timeval *now, void *private_data)
2632 struct smbd_server_connection *sconn =
2633 (struct smbd_server_connection *)private_data;
2635 if ((conn_num_open(sconn) == 0)
2636 || (conn_idle_all(sconn, now->tv_sec))) {
2637 DEBUG( 2, ( "Closing idle connection\n" ) );
2638 messaging_send(sconn->msg_ctx,
2639 messaging_server_id(sconn->msg_ctx),
2640 MSG_SHUTDOWN, &data_blob_null);
2641 return False;
2644 return True;
2648 * Do the recurring log file and smb.conf reload checks.
2651 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2653 struct smbd_server_connection *sconn = talloc_get_type_abort(
2654 private_data, struct smbd_server_connection);
2656 DEBUG(5, ("housekeeping\n"));
2658 change_to_root_user();
2660 /* update printer queue caches if necessary */
2661 update_monitored_printq_cache(sconn->msg_ctx);
2663 /* check if we need to reload services */
2664 check_reload(sconn, time_mono(NULL));
2667 * Force a log file check.
2669 force_check_log_size();
2670 check_log_size();
2671 return true;
2675 * Read an smb packet in the echo handler child, giving the parent
2676 * smbd one second to react once the socket becomes readable.
2679 struct smbd_echo_read_state {
2680 struct tevent_context *ev;
2681 struct smbd_server_connection *sconn;
2683 char *buf;
2684 size_t buflen;
2685 uint32_t seqnum;
2688 static void smbd_echo_read_readable(struct tevent_req *subreq);
2689 static void smbd_echo_read_waited(struct tevent_req *subreq);
2691 static struct tevent_req *smbd_echo_read_send(
2692 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2693 struct smbd_server_connection *sconn)
2695 struct tevent_req *req, *subreq;
2696 struct smbd_echo_read_state *state;
2698 req = tevent_req_create(mem_ctx, &state,
2699 struct smbd_echo_read_state);
2700 if (req == NULL) {
2701 return NULL;
2703 state->ev = ev;
2704 state->sconn = sconn;
2706 subreq = wait_for_read_send(state, ev, sconn->sock);
2707 if (tevent_req_nomem(subreq, req)) {
2708 return tevent_req_post(req, ev);
2710 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2711 return req;
2714 static void smbd_echo_read_readable(struct tevent_req *subreq)
2716 struct tevent_req *req = tevent_req_callback_data(
2717 subreq, struct tevent_req);
2718 struct smbd_echo_read_state *state = tevent_req_data(
2719 req, struct smbd_echo_read_state);
2720 bool ok;
2721 int err;
2723 ok = wait_for_read_recv(subreq, &err);
2724 TALLOC_FREE(subreq);
2725 if (!ok) {
2726 tevent_req_nterror(req, map_nt_error_from_unix(err));
2727 return;
2731 * Give the parent smbd one second to step in
2734 subreq = tevent_wakeup_send(
2735 state, state->ev, timeval_current_ofs(1, 0));
2736 if (tevent_req_nomem(subreq, req)) {
2737 return;
2739 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2742 static void smbd_echo_read_waited(struct tevent_req *subreq)
2744 struct tevent_req *req = tevent_req_callback_data(
2745 subreq, struct tevent_req);
2746 struct smbd_echo_read_state *state = tevent_req_data(
2747 req, struct smbd_echo_read_state);
2748 struct smbd_server_connection *sconn = state->sconn;
2749 bool ok;
2750 NTSTATUS status;
2751 size_t unread = 0;
2752 bool encrypted;
2754 ok = tevent_wakeup_recv(subreq);
2755 TALLOC_FREE(subreq);
2756 if (!ok) {
2757 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2758 return;
2761 ok = smbd_lock_socket_internal(sconn);
2762 if (!ok) {
2763 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2764 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2765 return;
2768 if (!fd_is_readable(sconn->sock)) {
2769 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2770 (int)getpid()));
2772 ok = smbd_unlock_socket_internal(sconn);
2773 if (!ok) {
2774 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2775 DEBUG(1, ("%s: failed to unlock socket\n",
2776 __location__));
2777 return;
2780 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2781 if (tevent_req_nomem(subreq, req)) {
2782 return;
2784 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2785 return;
2788 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2789 0 /* timeout */,
2790 &unread,
2791 &encrypted,
2792 &state->buflen,
2793 &state->seqnum,
2794 false /* trusted_channel*/);
2796 if (tevent_req_nterror(req, status)) {
2797 tevent_req_nterror(req, status);
2798 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2799 (int)getpid(), nt_errstr(status)));
2800 return;
2803 ok = smbd_unlock_socket_internal(sconn);
2804 if (!ok) {
2805 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2806 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2807 return;
2809 tevent_req_done(req);
2812 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2813 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2815 struct smbd_echo_read_state *state = tevent_req_data(
2816 req, struct smbd_echo_read_state);
2817 NTSTATUS status;
2819 if (tevent_req_is_nterror(req, &status)) {
2820 return status;
2822 *pbuf = talloc_move(mem_ctx, &state->buf);
2823 *pbuflen = state->buflen;
2824 *pseqnum = state->seqnum;
2825 return NT_STATUS_OK;
2828 struct smbd_echo_state {
2829 struct tevent_context *ev;
2830 struct iovec *pending;
2831 struct smbd_server_connection *sconn;
2832 int parent_pipe;
2834 struct tevent_fd *parent_fde;
2836 struct tevent_req *write_req;
2839 static void smbd_echo_writer_done(struct tevent_req *req);
2841 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2843 int num_pending;
2845 if (state->write_req != NULL) {
2846 return;
2849 num_pending = talloc_array_length(state->pending);
2850 if (num_pending == 0) {
2851 return;
2854 state->write_req = writev_send(state, state->ev, NULL,
2855 state->parent_pipe, false,
2856 state->pending, num_pending);
2857 if (state->write_req == NULL) {
2858 DEBUG(1, ("writev_send failed\n"));
2859 exit(1);
2862 talloc_steal(state->write_req, state->pending);
2863 state->pending = NULL;
2865 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2866 state);
2869 static void smbd_echo_writer_done(struct tevent_req *req)
2871 struct smbd_echo_state *state = tevent_req_callback_data(
2872 req, struct smbd_echo_state);
2873 ssize_t written;
2874 int err;
2876 written = writev_recv(req, &err);
2877 TALLOC_FREE(req);
2878 state->write_req = NULL;
2879 if (written == -1) {
2880 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2881 exit(1);
2883 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2884 smbd_echo_activate_writer(state);
2887 static bool smbd_echo_reply(struct smbd_echo_state *state,
2888 uint8_t *inbuf, size_t inbuf_len,
2889 uint32_t seqnum)
2891 struct smb_request req;
2892 uint16_t num_replies;
2893 char *outbuf;
2894 bool ok;
2896 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2897 DEBUG(10, ("Got netbios keepalive\n"));
2899 * Just swallow it
2901 return true;
2904 if (inbuf_len < smb_size) {
2905 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2906 return false;
2908 if (!valid_smb_header(state->sconn, inbuf)) {
2909 DEBUG(10, ("Got invalid SMB header\n"));
2910 return false;
2913 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2914 seqnum)) {
2915 return false;
2917 req.inbuf = inbuf;
2919 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2920 smb_messages[req.cmd].name
2921 ? smb_messages[req.cmd].name : "unknown"));
2923 if (req.cmd != SMBecho) {
2924 return false;
2926 if (req.wct < 1) {
2927 return false;
2930 num_replies = SVAL(req.vwv+0, 0);
2931 if (num_replies != 1) {
2932 /* Not a Windows "Hey, you're still there?" request */
2933 return false;
2936 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2937 1, req.buflen)) {
2938 DEBUG(10, ("create_outbuf failed\n"));
2939 return false;
2941 req.outbuf = (uint8_t *)outbuf;
2943 SSVAL(req.outbuf, smb_vwv0, num_replies);
2945 if (req.buflen > 0) {
2946 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2949 ok = srv_send_smb(req.sconn,
2950 (char *)outbuf,
2951 true, seqnum+1,
2952 false, &req.pcd);
2953 TALLOC_FREE(outbuf);
2954 if (!ok) {
2955 exit(1);
2958 return true;
2961 static void smbd_echo_exit(struct tevent_context *ev,
2962 struct tevent_fd *fde, uint16_t flags,
2963 void *private_data)
2965 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2966 exit(0);
2969 static void smbd_echo_got_packet(struct tevent_req *req);
2971 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2972 int parent_pipe)
2974 struct smbd_echo_state *state;
2975 struct tevent_req *read_req;
2977 state = talloc_zero(sconn, struct smbd_echo_state);
2978 if (state == NULL) {
2979 DEBUG(1, ("talloc failed\n"));
2980 return;
2982 state->sconn = sconn;
2983 state->parent_pipe = parent_pipe;
2984 state->ev = s3_tevent_context_init(state);
2985 if (state->ev == NULL) {
2986 DEBUG(1, ("tevent_context_init failed\n"));
2987 TALLOC_FREE(state);
2988 return;
2990 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2991 TEVENT_FD_READ, smbd_echo_exit,
2992 state);
2993 if (state->parent_fde == NULL) {
2994 DEBUG(1, ("tevent_add_fd failed\n"));
2995 TALLOC_FREE(state);
2996 return;
2999 read_req = smbd_echo_read_send(state, state->ev, sconn);
3000 if (read_req == NULL) {
3001 DEBUG(1, ("smbd_echo_read_send failed\n"));
3002 TALLOC_FREE(state);
3003 return;
3005 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3007 while (true) {
3008 if (tevent_loop_once(state->ev) == -1) {
3009 DEBUG(1, ("tevent_loop_once failed: %s\n",
3010 strerror(errno)));
3011 break;
3014 TALLOC_FREE(state);
3017 static void smbd_echo_got_packet(struct tevent_req *req)
3019 struct smbd_echo_state *state = tevent_req_callback_data(
3020 req, struct smbd_echo_state);
3021 NTSTATUS status;
3022 char *buf = NULL;
3023 size_t buflen = 0;
3024 uint32_t seqnum = 0;
3025 bool reply;
3027 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3028 TALLOC_FREE(req);
3029 if (!NT_STATUS_IS_OK(status)) {
3030 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3031 nt_errstr(status)));
3032 exit(1);
3035 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3036 if (!reply) {
3037 size_t num_pending;
3038 struct iovec *tmp;
3039 struct iovec *iov;
3041 num_pending = talloc_array_length(state->pending);
3042 tmp = talloc_realloc(state, state->pending, struct iovec,
3043 num_pending+1);
3044 if (tmp == NULL) {
3045 DEBUG(1, ("talloc_realloc failed\n"));
3046 exit(1);
3048 state->pending = tmp;
3050 if (buflen >= smb_size) {
3052 * place the seqnum in the packet so that the main process
3053 * can reply with signing
3055 SIVAL(buf, smb_ss_field, seqnum);
3056 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3059 iov = &state->pending[num_pending];
3060 iov->iov_base = talloc_move(state->pending, &buf);
3061 iov->iov_len = buflen;
3063 DEBUG(10,("echo_handler[%d]: forward to main\n",
3064 (int)getpid()));
3065 smbd_echo_activate_writer(state);
3068 req = smbd_echo_read_send(state, state->ev, state->sconn);
3069 if (req == NULL) {
3070 DEBUG(1, ("smbd_echo_read_send failed\n"));
3071 exit(1);
3073 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3078 * Handle SMBecho requests in a forked child process
3080 bool fork_echo_handler(struct smbd_server_connection *sconn)
3082 int listener_pipe[2];
3083 int res;
3084 pid_t child;
3086 res = pipe(listener_pipe);
3087 if (res == -1) {
3088 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3089 return false;
3091 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3092 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3093 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3094 goto fail;
3097 child = fork();
3098 if (child == 0) {
3099 NTSTATUS status;
3101 close(listener_pipe[0]);
3102 set_blocking(listener_pipe[1], false);
3104 status = reinit_after_fork(sconn->msg_ctx,
3105 sconn->ev_ctx,
3106 true);
3107 if (!NT_STATUS_IS_OK(status)) {
3108 DEBUG(1, ("reinit_after_fork failed: %s\n",
3109 nt_errstr(status)));
3110 exit(1);
3112 smbd_echo_loop(sconn, listener_pipe[1]);
3113 exit(0);
3115 close(listener_pipe[1]);
3116 listener_pipe[1] = -1;
3117 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3119 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3122 * Without smb signing this is the same as the normal smbd
3123 * listener. This needs to change once signing comes in.
3125 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3126 sconn,
3127 sconn->smb1.echo_handler.trusted_fd,
3128 TEVENT_FD_READ,
3129 smbd_server_echo_handler,
3130 sconn);
3131 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3132 DEBUG(1, ("event_add_fd failed\n"));
3133 goto fail;
3136 return true;
3138 fail:
3139 if (listener_pipe[0] != -1) {
3140 close(listener_pipe[0]);
3142 if (listener_pipe[1] != -1) {
3143 close(listener_pipe[1]);
3145 sconn->smb1.echo_handler.trusted_fd = -1;
3146 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3147 close(sconn->smb1.echo_handler.socket_lock_fd);
3149 sconn->smb1.echo_handler.trusted_fd = -1;
3150 sconn->smb1.echo_handler.socket_lock_fd = -1;
3151 return false;
3154 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3156 while (user) {
3157 if (user->session_info &&
3158 (user->session_info->unix_token->uid == uid)) {
3159 return true;
3161 user = user->next;
3163 return false;
3166 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3168 while (user) {
3169 if (user->session_info != NULL) {
3170 int i;
3171 struct security_unix_token *utok;
3173 utok = user->session_info->unix_token;
3174 if (utok->gid == gid) {
3175 return true;
3177 for(i=0; i<utok->ngroups; i++) {
3178 if (utok->groups[i] == gid) {
3179 return true;
3183 user = user->next;
3185 return false;
3188 static bool sid_in_use(const struct user_struct *user,
3189 const struct dom_sid *psid)
3191 while (user) {
3192 struct security_token *tok;
3194 if (user->session_info == NULL) {
3195 continue;
3197 tok = user->session_info->security_token;
3198 if (tok == NULL) {
3200 * Not sure session_info->security_token can
3201 * ever be NULL. This check might be not
3202 * necessary.
3204 continue;
3206 if (security_token_has_sid(tok, psid)) {
3207 return true;
3209 user = user->next;
3211 return false;
3214 static bool id_in_use(const struct user_struct *user,
3215 const struct id_cache_ref *id)
3217 switch(id->type) {
3218 case UID:
3219 return uid_in_use(user, id->id.uid);
3220 case GID:
3221 return gid_in_use(user, id->id.gid);
3222 case SID:
3223 return sid_in_use(user, &id->id.sid);
3224 default:
3225 break;
3227 return false;
3230 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3231 void *private_data,
3232 uint32_t msg_type,
3233 struct server_id server_id,
3234 DATA_BLOB* data)
3236 const char *msg = (data && data->data)
3237 ? (const char *)data->data : "<NULL>";
3238 struct id_cache_ref id;
3239 struct smbd_server_connection *sconn =
3240 talloc_get_type_abort(private_data,
3241 struct smbd_server_connection);
3243 if (!id_cache_ref_parse(msg, &id)) {
3244 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3245 return;
3248 if (id_in_use(sconn->users, &id)) {
3249 exit_server_cleanly(msg);
3251 id_cache_delete_from_cache(&id);
3254 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3255 enum protocol_types protocol)
3257 NTSTATUS status;
3259 set_Protocol(protocol);
3260 conn->protocol = protocol;
3262 if (protocol >= PROTOCOL_SMB2_02) {
3263 status = smb2srv_session_table_init(conn);
3264 if (!NT_STATUS_IS_OK(status)) {
3265 return status;
3268 status = smb2srv_open_table_init(conn);
3269 if (!NT_STATUS_IS_OK(status)) {
3270 return status;
3272 } else {
3273 status = smb1srv_session_table_init(conn);
3274 if (!NT_STATUS_IS_OK(status)) {
3275 return status;
3278 status = smb1srv_tcon_table_init(conn);
3279 if (!NT_STATUS_IS_OK(status)) {
3280 return status;
3283 status = smb1srv_open_table_init(conn);
3284 if (!NT_STATUS_IS_OK(status)) {
3285 return status;
3289 return NT_STATUS_OK;
3292 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3293 void *private_data)
3295 struct smbXsrv_connection *conn =
3296 talloc_get_type_abort(private_data,
3297 struct smbXsrv_connection);
3299 switch (point) {
3300 case TEVENT_TRACE_BEFORE_WAIT:
3302 * This just removes compiler warning
3303 * without profile support
3305 conn->smbd_idle_profstamp = 0;
3306 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3307 break;
3308 case TEVENT_TRACE_AFTER_WAIT:
3309 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3310 break;
3314 /****************************************************************************
3315 Process commands from the client
3316 ****************************************************************************/
3318 void smbd_process(struct tevent_context *ev_ctx,
3319 struct messaging_context *msg_ctx,
3320 int sock_fd,
3321 bool interactive)
3323 TALLOC_CTX *frame = talloc_stackframe();
3324 struct smbXsrv_connection *conn;
3325 struct smbd_server_connection *sconn;
3326 struct sockaddr_storage ss;
3327 struct sockaddr *sa = NULL;
3328 socklen_t sa_socklen;
3329 struct tsocket_address *local_address = NULL;
3330 struct tsocket_address *remote_address = NULL;
3331 const char *locaddr = NULL;
3332 const char *remaddr = NULL;
3333 char *rhost;
3334 int ret;
3336 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3337 if (conn == NULL) {
3338 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3339 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3342 conn->ev_ctx = ev_ctx;
3343 conn->msg_ctx = msg_ctx;
3345 sconn = talloc_zero(conn, struct smbd_server_connection);
3346 if (!sconn) {
3347 exit_server("failed to create smbd_server_connection");
3350 conn->sconn = sconn;
3351 sconn->conn = conn;
3354 * TODO: remove this...:-)
3356 global_smbXsrv_connection = conn;
3358 sconn->ev_ctx = ev_ctx;
3359 sconn->msg_ctx = msg_ctx;
3360 sconn->sock = sock_fd;
3361 sconn->smb1.echo_handler.trusted_fd = -1;
3362 sconn->smb1.echo_handler.socket_lock_fd = -1;
3364 if (!interactive) {
3365 smbd_setup_sig_term_handler(sconn);
3366 smbd_setup_sig_hup_handler(sconn);
3368 if (!serverid_register(messaging_server_id(msg_ctx),
3369 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3370 |FLAG_MSG_DBWRAP
3371 |FLAG_MSG_PRINT_GENERAL)) {
3372 exit_server_cleanly("Could not register myself in "
3373 "serverid.tdb");
3377 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3379 * We're not making the decision here,
3380 * we're just allowing the client
3381 * to decide between SMB1 and SMB2
3382 * with the first negprot
3383 * packet.
3385 sconn->using_smb2 = true;
3388 /* Ensure child is set to blocking mode */
3389 set_blocking(sconn->sock,True);
3391 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3392 set_socket_options(sconn->sock, lp_socket_options());
3394 sa = (struct sockaddr *)(void *)&ss;
3395 sa_socklen = sizeof(ss);
3396 ret = getpeername(sconn->sock, sa, &sa_socklen);
3397 if (ret != 0) {
3398 int level = (errno == ENOTCONN)?2:0;
3399 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3400 exit_server_cleanly("getpeername() failed.\n");
3402 ret = tsocket_address_bsd_from_sockaddr(sconn,
3403 sa, sa_socklen,
3404 &remote_address);
3405 if (ret != 0) {
3406 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3407 __location__, strerror(errno)));
3408 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3411 sa = (struct sockaddr *)(void *)&ss;
3412 sa_socklen = sizeof(ss);
3413 ret = getsockname(sconn->sock, sa, &sa_socklen);
3414 if (ret != 0) {
3415 int level = (errno == ENOTCONN)?2:0;
3416 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3417 exit_server_cleanly("getsockname() failed.\n");
3419 ret = tsocket_address_bsd_from_sockaddr(sconn,
3420 sa, sa_socklen,
3421 &local_address);
3422 if (ret != 0) {
3423 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3424 __location__, strerror(errno)));
3425 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3428 sconn->local_address = local_address;
3429 sconn->remote_address = remote_address;
3431 if (tsocket_address_is_inet(local_address, "ip")) {
3432 locaddr = tsocket_address_inet_addr_string(
3433 sconn->local_address,
3434 talloc_tos());
3435 if (locaddr == NULL) {
3436 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3437 __location__, strerror(errno)));
3438 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3440 } else {
3441 locaddr = "0.0.0.0";
3444 if (tsocket_address_is_inet(remote_address, "ip")) {
3445 remaddr = tsocket_address_inet_addr_string(
3446 sconn->remote_address,
3447 talloc_tos());
3448 if (remaddr == NULL) {
3449 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3450 __location__, strerror(errno)));
3451 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3453 } else {
3454 remaddr = "0.0.0.0";
3457 /* this is needed so that we get decent entries
3458 in smbstatus for port 445 connects */
3459 set_remote_machine_name(remaddr, false);
3460 reload_services(sconn, conn_snum_used, true);
3463 * Before the first packet, check the global hosts allow/ hosts deny
3464 * parameters before doing any parsing of packets passed to us by the
3465 * client. This prevents attacks on our parsing code from hosts not in
3466 * the hosts allow list.
3469 ret = get_remote_hostname(remote_address,
3470 &rhost,
3471 talloc_tos());
3472 if (ret < 0) {
3473 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3474 __location__, strerror(errno)));
3475 exit_server_cleanly("get_remote_hostname failed.\n");
3477 if (strequal(rhost, "UNKNOWN")) {
3478 rhost = talloc_strdup(talloc_tos(), remaddr);
3480 sconn->remote_hostname = talloc_move(sconn, &rhost);
3482 sub_set_socket_ids(remaddr,
3483 sconn->remote_hostname,
3484 locaddr);
3486 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3487 sconn->remote_hostname,
3488 remaddr)) {
3490 * send a negative session response "not listening on calling
3491 * name"
3493 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3494 DEBUG( 1, ("Connection denied from %s to %s\n",
3495 tsocket_address_string(remote_address, talloc_tos()),
3496 tsocket_address_string(local_address, talloc_tos())));
3497 (void)srv_send_smb(sconn,(char *)buf, false,
3498 0, false, NULL);
3499 exit_server_cleanly("connection denied");
3502 DEBUG(10, ("Connection allowed from %s to %s\n",
3503 tsocket_address_string(remote_address, talloc_tos()),
3504 tsocket_address_string(local_address, talloc_tos())));
3506 if (lp_preload_modules()) {
3507 smb_load_modules(lp_preload_modules());
3510 smb_perfcount_init();
3512 if (!init_account_policy()) {
3513 exit_server("Could not open account policy tdb.\n");
3516 if (*lp_rootdir(talloc_tos())) {
3517 if (chroot(lp_rootdir(talloc_tos())) != 0) {
3518 DEBUG(0,("Failed to change root to %s\n",
3519 lp_rootdir(talloc_tos())));
3520 exit_server("Failed to chroot()");
3522 if (chdir("/") == -1) {
3523 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
3524 exit_server("Failed to chroot()");
3526 DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
3529 if (!srv_init_signing(sconn)) {
3530 exit_server("Failed to init smb_signing");
3533 if (!file_init(sconn)) {
3534 exit_server("file_init() failed");
3537 /* Setup oplocks */
3538 if (!init_oplocks(sconn))
3539 exit_server("Failed to init oplocks");
3541 /* register our message handlers */
3542 messaging_register(sconn->msg_ctx, sconn,
3543 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3544 messaging_register(sconn->msg_ctx, sconn,
3545 MSG_SMB_CLOSE_FILE, msg_close_file);
3546 messaging_register(sconn->msg_ctx, sconn,
3547 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3549 id_cache_register_msgs(sconn->msg_ctx);
3550 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3551 messaging_register(sconn->msg_ctx, sconn,
3552 ID_CACHE_KILL, smbd_id_cache_kill);
3554 messaging_deregister(sconn->msg_ctx,
3555 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3556 messaging_register(sconn->msg_ctx, sconn,
3557 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3559 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3560 NULL);
3561 messaging_register(sconn->msg_ctx, sconn,
3562 MSG_SMB_KILL_CLIENT_IP,
3563 msg_kill_client_ip);
3565 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3568 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3569 * MSGs to all child processes
3571 messaging_deregister(sconn->msg_ctx,
3572 MSG_DEBUG, NULL);
3573 messaging_register(sconn->msg_ctx, NULL,
3574 MSG_DEBUG, debug_message);
3576 if ((lp_keepalive() != 0)
3577 && !(event_add_idle(ev_ctx, NULL,
3578 timeval_set(lp_keepalive(), 0),
3579 "keepalive", keepalive_fn,
3580 sconn))) {
3581 DEBUG(0, ("Could not add keepalive event\n"));
3582 exit(1);
3585 if (!(event_add_idle(ev_ctx, NULL,
3586 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3587 "deadtime", deadtime_fn, sconn))) {
3588 DEBUG(0, ("Could not add deadtime event\n"));
3589 exit(1);
3592 if (!(event_add_idle(ev_ctx, NULL,
3593 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3594 "housekeeping", housekeeping_fn, sconn))) {
3595 DEBUG(0, ("Could not add housekeeping event\n"));
3596 exit(1);
3599 #ifdef CLUSTER_SUPPORT
3601 if (lp_clustering()) {
3603 * We need to tell ctdb about our client's TCP
3604 * connection, so that for failover ctdbd can send
3605 * tickle acks, triggering a reconnection by the
3606 * client.
3609 struct sockaddr_storage srv, clnt;
3611 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3612 NTSTATUS status;
3613 status = smbd_register_ips(sconn, &srv, &clnt);
3614 if (!NT_STATUS_IS_OK(status)) {
3615 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3616 nt_errstr(status)));
3618 } else {
3619 int level = (errno == ENOTCONN)?2:0;
3620 DEBUG(level,("Unable to get tcp info for "
3621 "smbd_register_ips: %s\n",
3622 strerror(errno)));
3623 exit_server_cleanly("client_get_tcp_info() failed.\n");
3627 #endif
3629 sconn->nbt.got_session = false;
3631 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3633 sconn->smb1.sessions.done_sesssetup = false;
3634 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3636 if (!init_dptrs(sconn)) {
3637 exit_server("init_dptrs() failed");
3640 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3641 sconn,
3642 sconn->sock,
3643 TEVENT_FD_READ,
3644 smbd_server_connection_handler,
3645 sconn);
3646 if (!sconn->smb1.fde) {
3647 exit_server("failed to create smbd_server_connection fde");
3650 sconn->conn->local_address = sconn->local_address;
3651 sconn->conn->remote_address = sconn->remote_address;
3652 sconn->conn->remote_hostname = sconn->remote_hostname;
3653 sconn->conn->protocol = PROTOCOL_NONE;
3655 TALLOC_FREE(frame);
3657 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3659 while (True) {
3660 frame = talloc_stackframe_pool(8192);
3662 errno = 0;
3663 if (tevent_loop_once(ev_ctx) == -1) {
3664 if (errno != EINTR) {
3665 DEBUG(3, ("tevent_loop_once failed: %s,"
3666 " exiting\n", strerror(errno) ));
3667 break;
3671 TALLOC_FREE(frame);
3674 exit_server_cleanly(NULL);
3677 bool req_is_in_chain(const struct smb_request *req)
3679 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3681 * We're right now handling a subsequent request, so we must
3682 * be in a chain
3684 return true;
3687 if (!is_andx_req(req->cmd)) {
3688 return false;
3691 if (req->wct < 2) {
3693 * Okay, an illegal request, but definitely not chained :-)
3695 return false;
3698 return (CVAL(req->vwv+0, 0) != 0xFF);