s3:smbd: Fix off-by 4 error in wrap protection code in create_outbuf()
[Samba.git] / source3 / smbd / process.c
blob1ebda799c96937eba911502b2f0fa614f725ed96
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 size_t nwritten=0;
153 ssize_t ret;
154 char *buf_out = buffer;
156 smbd_lock_socket(sconn);
158 if (do_signing) {
159 /* Sign the outgoing packet if required. */
160 srv_calculate_sign_mac(sconn, buf_out, seqnum);
163 if (do_encrypt) {
164 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
165 if (!NT_STATUS_IS_OK(status)) {
166 DEBUG(0, ("send_smb: SMB encryption failed "
167 "on outgoing packet! Error %s\n",
168 nt_errstr(status) ));
169 goto out;
173 len = smb_len_large(buf_out) + 4;
175 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
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 true;
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 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
668 msg,
669 end_time,
670 smbd_deferred_open_timer,
671 msg);
672 if (!msg->te) {
673 DEBUG(0,("push_message: event_add_timed failed\n"));
674 TALLOC_FREE(msg);
675 return false;
678 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
679 struct pending_message_list *);
681 DEBUG(10,("push_message: pushed message length %u on "
682 "deferred_open_queue\n", (unsigned int)msg_len));
684 return True;
687 /****************************************************************************
688 Function to delete a sharing violation open message by mid.
689 ****************************************************************************/
691 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
692 uint64_t mid)
694 struct pending_message_list *pml;
696 if (sconn->using_smb2) {
697 remove_deferred_open_message_smb2(sconn, mid);
698 return;
701 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
702 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
703 DEBUG(10,("remove_deferred_open_message_smb: "
704 "deleting mid %llu len %u\n",
705 (unsigned long long)mid,
706 (unsigned int)pml->buf.length ));
707 DLIST_REMOVE(sconn->deferred_open_queue, pml);
708 TALLOC_FREE(pml);
709 return;
714 /****************************************************************************
715 Move a sharing violation open retry message to the front of the list and
716 schedule it for immediate processing.
717 ****************************************************************************/
719 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
720 uint64_t mid)
722 struct pending_message_list *pml;
723 int i = 0;
725 if (sconn->using_smb2) {
726 return schedule_deferred_open_message_smb2(sconn, mid);
729 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
730 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
732 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
733 "msg_mid = %llu\n",
734 i++,
735 (unsigned long long)msg_mid ));
737 if (mid == msg_mid) {
738 struct tevent_timer *te;
740 if (pml->processed) {
741 /* A processed message should not be
742 * rescheduled. */
743 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
744 "message mid %llu was already processed\n",
745 (unsigned long long)msg_mid ));
746 continue;
749 DEBUG(10,("schedule_deferred_open_message_smb: "
750 "scheduling mid %llu\n",
751 (unsigned long long)mid ));
753 te = tevent_add_timer(pml->sconn->ev_ctx,
754 pml,
755 timeval_zero(),
756 smbd_deferred_open_timer,
757 pml);
758 if (!te) {
759 DEBUG(10,("schedule_deferred_open_message_smb: "
760 "event_add_timed() failed, "
761 "skipping mid %llu\n",
762 (unsigned long long)msg_mid ));
765 TALLOC_FREE(pml->te);
766 pml->te = te;
767 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
768 return true;
772 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
773 "find message mid %llu\n",
774 (unsigned long long)mid ));
776 return false;
779 /****************************************************************************
780 Return true if this mid is on the deferred queue and was not yet processed.
781 ****************************************************************************/
783 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
785 struct pending_message_list *pml;
787 if (sconn->using_smb2) {
788 return open_was_deferred_smb2(sconn, mid);
791 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
792 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
793 return True;
796 return False;
799 /****************************************************************************
800 Return the message queued by this mid.
801 ****************************************************************************/
803 static struct pending_message_list *get_deferred_open_message_smb(
804 struct smbd_server_connection *sconn, uint64_t mid)
806 struct pending_message_list *pml;
808 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
809 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
810 return pml;
813 return NULL;
816 /****************************************************************************
817 Get the state data queued by this mid.
818 ****************************************************************************/
820 bool get_deferred_open_message_state(struct smb_request *smbreq,
821 struct timeval *p_request_time,
822 void **pp_state)
824 struct pending_message_list *pml;
826 if (smbreq->sconn->using_smb2) {
827 return get_deferred_open_message_state_smb2(smbreq->smb2req,
828 p_request_time,
829 pp_state);
832 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
833 if (!pml) {
834 return false;
836 if (p_request_time) {
837 *p_request_time = pml->request_time;
839 if (pp_state) {
840 *pp_state = (void *)pml->private_data.data;
842 return true;
845 /****************************************************************************
846 Function to push a deferred open smb message onto a linked list of local smb
847 messages ready for processing.
848 ****************************************************************************/
850 bool push_deferred_open_message_smb(struct smb_request *req,
851 struct timeval request_time,
852 struct timeval timeout,
853 struct file_id id,
854 char *private_data, size_t priv_len)
856 struct timeval end_time;
858 if (req->smb2req) {
859 return push_deferred_open_message_smb2(req->smb2req,
860 request_time,
861 timeout,
863 private_data,
864 priv_len);
867 if (req->unread_bytes) {
868 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
869 "unread_bytes = %u\n",
870 (unsigned int)req->unread_bytes ));
871 smb_panic("push_deferred_open_message_smb: "
872 "logic error unread_bytes != 0" );
875 end_time = timeval_sum(&request_time, &timeout);
877 DEBUG(10,("push_deferred_open_message_smb: pushing message "
878 "len %u mid %llu timeout time [%u.%06u]\n",
879 (unsigned int) smb_len(req->inbuf)+4,
880 (unsigned long long)req->mid,
881 (unsigned int)end_time.tv_sec,
882 (unsigned int)end_time.tv_usec));
884 return push_queued_message(req, request_time, end_time,
885 private_data, priv_len);
888 static void smbd_sig_term_handler(struct tevent_context *ev,
889 struct tevent_signal *se,
890 int signum,
891 int count,
892 void *siginfo,
893 void *private_data)
895 exit_server_cleanly("termination signal");
898 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
900 struct tevent_signal *se;
902 se = tevent_add_signal(sconn->ev_ctx,
903 sconn,
904 SIGTERM, 0,
905 smbd_sig_term_handler,
906 sconn);
907 if (!se) {
908 exit_server("failed to setup SIGTERM handler");
912 static void smbd_sig_hup_handler(struct tevent_context *ev,
913 struct tevent_signal *se,
914 int signum,
915 int count,
916 void *siginfo,
917 void *private_data)
919 struct smbd_server_connection *sconn =
920 talloc_get_type_abort(private_data,
921 struct smbd_server_connection);
923 change_to_root_user();
924 DEBUG(1,("Reloading services after SIGHUP\n"));
925 reload_services(sconn, conn_snum_used, false);
928 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
930 struct tevent_signal *se;
932 se = tevent_add_signal(sconn->ev_ctx,
933 sconn,
934 SIGHUP, 0,
935 smbd_sig_hup_handler,
936 sconn);
937 if (!se) {
938 exit_server("failed to setup SIGHUP handler");
942 static void smbd_conf_updated(struct messaging_context *msg,
943 void *private_data,
944 uint32_t msg_type,
945 struct server_id server_id,
946 DATA_BLOB *data)
948 struct smbd_server_connection *sconn =
949 talloc_get_type_abort(private_data,
950 struct smbd_server_connection);
952 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
953 "updated. Reloading.\n"));
954 change_to_root_user();
955 reload_services(sconn, conn_snum_used, false);
959 * Only allow 5 outstanding trans requests. We're allocating memory, so
960 * prevent a DoS.
963 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
965 int count = 0;
966 for (; list != NULL; list = list->next) {
968 if (list->mid == mid) {
969 return NT_STATUS_INVALID_PARAMETER;
972 count += 1;
974 if (count > 5) {
975 return NT_STATUS_INSUFFICIENT_RESOURCES;
978 return NT_STATUS_OK;
982 These flags determine some of the permissions required to do an operation
984 Note that I don't set NEED_WRITE on some write operations because they
985 are used by some brain-dead clients when printing, and I don't want to
986 force write permissions on print services.
988 #define AS_USER (1<<0)
989 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
990 #define TIME_INIT (1<<2)
991 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
992 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
993 #define DO_CHDIR (1<<6)
996 define a list of possible SMB messages and their corresponding
997 functions. Any message that has a NULL function is unimplemented -
998 please feel free to contribute implementations!
1000 static const struct smb_message_struct {
1001 const char *name;
1002 void (*fn)(struct smb_request *req);
1003 int flags;
1004 } smb_messages[256] = {
1006 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1007 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1008 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1009 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1010 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1011 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1012 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1013 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1014 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1015 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1016 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1017 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1018 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1019 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1020 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1021 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1022 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1023 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1024 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1025 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1026 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1027 /* 0x15 */ { NULL, NULL, 0 },
1028 /* 0x16 */ { NULL, NULL, 0 },
1029 /* 0x17 */ { NULL, NULL, 0 },
1030 /* 0x18 */ { NULL, NULL, 0 },
1031 /* 0x19 */ { NULL, NULL, 0 },
1032 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1033 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1034 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1035 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1036 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1037 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1038 /* 0x20 */ { "SMBwritec", NULL,0},
1039 /* 0x21 */ { NULL, NULL, 0 },
1040 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1041 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1042 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1043 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1044 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1045 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1046 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1047 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1048 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1049 /* 0x2b */ { "SMBecho",reply_echo,0},
1050 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1051 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1052 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1053 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1054 /* 0x30 */ { NULL, NULL, 0 },
1055 /* 0x31 */ { NULL, NULL, 0 },
1056 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1057 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1058 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1059 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1060 /* 0x36 */ { NULL, NULL, 0 },
1061 /* 0x37 */ { NULL, NULL, 0 },
1062 /* 0x38 */ { NULL, NULL, 0 },
1063 /* 0x39 */ { NULL, NULL, 0 },
1064 /* 0x3a */ { NULL, NULL, 0 },
1065 /* 0x3b */ { NULL, NULL, 0 },
1066 /* 0x3c */ { NULL, NULL, 0 },
1067 /* 0x3d */ { NULL, NULL, 0 },
1068 /* 0x3e */ { NULL, NULL, 0 },
1069 /* 0x3f */ { NULL, NULL, 0 },
1070 /* 0x40 */ { NULL, NULL, 0 },
1071 /* 0x41 */ { NULL, NULL, 0 },
1072 /* 0x42 */ { NULL, NULL, 0 },
1073 /* 0x43 */ { NULL, NULL, 0 },
1074 /* 0x44 */ { NULL, NULL, 0 },
1075 /* 0x45 */ { NULL, NULL, 0 },
1076 /* 0x46 */ { NULL, NULL, 0 },
1077 /* 0x47 */ { NULL, NULL, 0 },
1078 /* 0x48 */ { NULL, NULL, 0 },
1079 /* 0x49 */ { NULL, NULL, 0 },
1080 /* 0x4a */ { NULL, NULL, 0 },
1081 /* 0x4b */ { NULL, NULL, 0 },
1082 /* 0x4c */ { NULL, NULL, 0 },
1083 /* 0x4d */ { NULL, NULL, 0 },
1084 /* 0x4e */ { NULL, NULL, 0 },
1085 /* 0x4f */ { NULL, NULL, 0 },
1086 /* 0x50 */ { NULL, NULL, 0 },
1087 /* 0x51 */ { NULL, NULL, 0 },
1088 /* 0x52 */ { NULL, NULL, 0 },
1089 /* 0x53 */ { NULL, NULL, 0 },
1090 /* 0x54 */ { NULL, NULL, 0 },
1091 /* 0x55 */ { NULL, NULL, 0 },
1092 /* 0x56 */ { NULL, NULL, 0 },
1093 /* 0x57 */ { NULL, NULL, 0 },
1094 /* 0x58 */ { NULL, NULL, 0 },
1095 /* 0x59 */ { NULL, NULL, 0 },
1096 /* 0x5a */ { NULL, NULL, 0 },
1097 /* 0x5b */ { NULL, NULL, 0 },
1098 /* 0x5c */ { NULL, NULL, 0 },
1099 /* 0x5d */ { NULL, NULL, 0 },
1100 /* 0x5e */ { NULL, NULL, 0 },
1101 /* 0x5f */ { NULL, NULL, 0 },
1102 /* 0x60 */ { NULL, NULL, 0 },
1103 /* 0x61 */ { NULL, NULL, 0 },
1104 /* 0x62 */ { NULL, NULL, 0 },
1105 /* 0x63 */ { NULL, NULL, 0 },
1106 /* 0x64 */ { NULL, NULL, 0 },
1107 /* 0x65 */ { NULL, NULL, 0 },
1108 /* 0x66 */ { NULL, NULL, 0 },
1109 /* 0x67 */ { NULL, NULL, 0 },
1110 /* 0x68 */ { NULL, NULL, 0 },
1111 /* 0x69 */ { NULL, NULL, 0 },
1112 /* 0x6a */ { NULL, NULL, 0 },
1113 /* 0x6b */ { NULL, NULL, 0 },
1114 /* 0x6c */ { NULL, NULL, 0 },
1115 /* 0x6d */ { NULL, NULL, 0 },
1116 /* 0x6e */ { NULL, NULL, 0 },
1117 /* 0x6f */ { NULL, NULL, 0 },
1118 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1119 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1120 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1121 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1122 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1123 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1124 /* 0x76 */ { NULL, NULL, 0 },
1125 /* 0x77 */ { NULL, NULL, 0 },
1126 /* 0x78 */ { NULL, NULL, 0 },
1127 /* 0x79 */ { NULL, NULL, 0 },
1128 /* 0x7a */ { NULL, NULL, 0 },
1129 /* 0x7b */ { NULL, NULL, 0 },
1130 /* 0x7c */ { NULL, NULL, 0 },
1131 /* 0x7d */ { NULL, NULL, 0 },
1132 /* 0x7e */ { NULL, NULL, 0 },
1133 /* 0x7f */ { NULL, NULL, 0 },
1134 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1135 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1136 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1137 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1138 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1139 /* 0x85 */ { NULL, NULL, 0 },
1140 /* 0x86 */ { NULL, NULL, 0 },
1141 /* 0x87 */ { NULL, NULL, 0 },
1142 /* 0x88 */ { NULL, NULL, 0 },
1143 /* 0x89 */ { NULL, NULL, 0 },
1144 /* 0x8a */ { NULL, NULL, 0 },
1145 /* 0x8b */ { NULL, NULL, 0 },
1146 /* 0x8c */ { NULL, NULL, 0 },
1147 /* 0x8d */ { NULL, NULL, 0 },
1148 /* 0x8e */ { NULL, NULL, 0 },
1149 /* 0x8f */ { NULL, NULL, 0 },
1150 /* 0x90 */ { NULL, NULL, 0 },
1151 /* 0x91 */ { NULL, NULL, 0 },
1152 /* 0x92 */ { NULL, NULL, 0 },
1153 /* 0x93 */ { NULL, NULL, 0 },
1154 /* 0x94 */ { NULL, NULL, 0 },
1155 /* 0x95 */ { NULL, NULL, 0 },
1156 /* 0x96 */ { NULL, NULL, 0 },
1157 /* 0x97 */ { NULL, NULL, 0 },
1158 /* 0x98 */ { NULL, NULL, 0 },
1159 /* 0x99 */ { NULL, NULL, 0 },
1160 /* 0x9a */ { NULL, NULL, 0 },
1161 /* 0x9b */ { NULL, NULL, 0 },
1162 /* 0x9c */ { NULL, NULL, 0 },
1163 /* 0x9d */ { NULL, NULL, 0 },
1164 /* 0x9e */ { NULL, NULL, 0 },
1165 /* 0x9f */ { NULL, NULL, 0 },
1166 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1167 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1168 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1169 /* 0xa3 */ { NULL, NULL, 0 },
1170 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1171 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1172 /* 0xa6 */ { NULL, NULL, 0 },
1173 /* 0xa7 */ { NULL, NULL, 0 },
1174 /* 0xa8 */ { NULL, NULL, 0 },
1175 /* 0xa9 */ { NULL, NULL, 0 },
1176 /* 0xaa */ { NULL, NULL, 0 },
1177 /* 0xab */ { NULL, NULL, 0 },
1178 /* 0xac */ { NULL, NULL, 0 },
1179 /* 0xad */ { NULL, NULL, 0 },
1180 /* 0xae */ { NULL, NULL, 0 },
1181 /* 0xaf */ { NULL, NULL, 0 },
1182 /* 0xb0 */ { NULL, NULL, 0 },
1183 /* 0xb1 */ { NULL, NULL, 0 },
1184 /* 0xb2 */ { NULL, NULL, 0 },
1185 /* 0xb3 */ { NULL, NULL, 0 },
1186 /* 0xb4 */ { NULL, NULL, 0 },
1187 /* 0xb5 */ { NULL, NULL, 0 },
1188 /* 0xb6 */ { NULL, NULL, 0 },
1189 /* 0xb7 */ { NULL, NULL, 0 },
1190 /* 0xb8 */ { NULL, NULL, 0 },
1191 /* 0xb9 */ { NULL, NULL, 0 },
1192 /* 0xba */ { NULL, NULL, 0 },
1193 /* 0xbb */ { NULL, NULL, 0 },
1194 /* 0xbc */ { NULL, NULL, 0 },
1195 /* 0xbd */ { NULL, NULL, 0 },
1196 /* 0xbe */ { NULL, NULL, 0 },
1197 /* 0xbf */ { NULL, NULL, 0 },
1198 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1199 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1200 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1201 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1202 /* 0xc4 */ { NULL, NULL, 0 },
1203 /* 0xc5 */ { NULL, NULL, 0 },
1204 /* 0xc6 */ { NULL, NULL, 0 },
1205 /* 0xc7 */ { NULL, NULL, 0 },
1206 /* 0xc8 */ { NULL, NULL, 0 },
1207 /* 0xc9 */ { NULL, NULL, 0 },
1208 /* 0xca */ { NULL, NULL, 0 },
1209 /* 0xcb */ { NULL, NULL, 0 },
1210 /* 0xcc */ { NULL, NULL, 0 },
1211 /* 0xcd */ { NULL, NULL, 0 },
1212 /* 0xce */ { NULL, NULL, 0 },
1213 /* 0xcf */ { NULL, NULL, 0 },
1214 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1215 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1216 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1217 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1218 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1219 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1220 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1221 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1222 /* 0xd8 */ { NULL, NULL, 0 },
1223 /* 0xd9 */ { NULL, NULL, 0 },
1224 /* 0xda */ { NULL, NULL, 0 },
1225 /* 0xdb */ { NULL, NULL, 0 },
1226 /* 0xdc */ { NULL, NULL, 0 },
1227 /* 0xdd */ { NULL, NULL, 0 },
1228 /* 0xde */ { NULL, NULL, 0 },
1229 /* 0xdf */ { NULL, NULL, 0 },
1230 /* 0xe0 */ { NULL, NULL, 0 },
1231 /* 0xe1 */ { NULL, NULL, 0 },
1232 /* 0xe2 */ { NULL, NULL, 0 },
1233 /* 0xe3 */ { NULL, NULL, 0 },
1234 /* 0xe4 */ { NULL, NULL, 0 },
1235 /* 0xe5 */ { NULL, NULL, 0 },
1236 /* 0xe6 */ { NULL, NULL, 0 },
1237 /* 0xe7 */ { NULL, NULL, 0 },
1238 /* 0xe8 */ { NULL, NULL, 0 },
1239 /* 0xe9 */ { NULL, NULL, 0 },
1240 /* 0xea */ { NULL, NULL, 0 },
1241 /* 0xeb */ { NULL, NULL, 0 },
1242 /* 0xec */ { NULL, NULL, 0 },
1243 /* 0xed */ { NULL, NULL, 0 },
1244 /* 0xee */ { NULL, NULL, 0 },
1245 /* 0xef */ { NULL, NULL, 0 },
1246 /* 0xf0 */ { NULL, NULL, 0 },
1247 /* 0xf1 */ { NULL, NULL, 0 },
1248 /* 0xf2 */ { NULL, NULL, 0 },
1249 /* 0xf3 */ { NULL, NULL, 0 },
1250 /* 0xf4 */ { NULL, NULL, 0 },
1251 /* 0xf5 */ { NULL, NULL, 0 },
1252 /* 0xf6 */ { NULL, NULL, 0 },
1253 /* 0xf7 */ { NULL, NULL, 0 },
1254 /* 0xf8 */ { NULL, NULL, 0 },
1255 /* 0xf9 */ { NULL, NULL, 0 },
1256 /* 0xfa */ { NULL, NULL, 0 },
1257 /* 0xfb */ { NULL, NULL, 0 },
1258 /* 0xfc */ { NULL, NULL, 0 },
1259 /* 0xfd */ { NULL, NULL, 0 },
1260 /* 0xfe */ { NULL, NULL, 0 },
1261 /* 0xff */ { NULL, NULL, 0 }
1265 /*******************************************************************
1266 allocate and initialize a reply packet
1267 ********************************************************************/
1269 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1270 const char *inbuf, char **outbuf, uint8_t num_words,
1271 uint32_t num_bytes)
1273 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1276 * Protect against integer wrap.
1277 * The SMB layer reply can be up to 0xFFFFFF bytes.
1279 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1280 char *msg;
1281 if (asprintf(&msg, "num_bytes too large: %u",
1282 (unsigned)num_bytes) == -1) {
1283 msg = discard_const_p(char, "num_bytes too large");
1285 smb_panic(msg);
1289 * Here we include the NBT header for now.
1291 *outbuf = talloc_array(mem_ctx, char,
1292 NBT_HDR_SIZE + smb_len);
1293 if (*outbuf == NULL) {
1294 return false;
1297 construct_reply_common(req, inbuf, *outbuf);
1298 srv_set_message(*outbuf, num_words, num_bytes, false);
1300 * Zero out the word area, the caller has to take care of the bcc area
1301 * himself
1303 if (num_words != 0) {
1304 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1307 return true;
1310 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1312 char *outbuf;
1313 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1314 num_bytes)) {
1315 smb_panic("could not allocate output buffer\n");
1317 req->outbuf = (uint8_t *)outbuf;
1321 /*******************************************************************
1322 Dump a packet to a file.
1323 ********************************************************************/
1325 static void smb_dump(const char *name, int type, const char *data)
1327 size_t len;
1328 int fd, i;
1329 char *fname = NULL;
1330 if (DEBUGLEVEL < 50) {
1331 return;
1334 len = smb_len_tcp(data)+4;
1335 for (i=1;i<100;i++) {
1336 fname = talloc_asprintf(talloc_tos(),
1337 "/tmp/%s.%d.%s",
1338 name,
1340 type ? "req" : "resp");
1341 if (fname == NULL) {
1342 return;
1344 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1345 if (fd != -1 || errno != EEXIST) break;
1346 TALLOC_FREE(fname);
1348 if (fd != -1) {
1349 ssize_t ret = write(fd, data, len);
1350 if (ret != len)
1351 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1352 close(fd);
1353 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1355 TALLOC_FREE(fname);
1358 /****************************************************************************
1359 Prepare everything for calling the actual request function, and potentially
1360 call the request function via the "new" interface.
1362 Return False if the "legacy" function needs to be called, everything is
1363 prepared.
1365 Return True if we're done.
1367 I know this API sucks, but it is the one with the least code change I could
1368 find.
1369 ****************************************************************************/
1371 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1373 int flags;
1374 uint64_t session_tag;
1375 connection_struct *conn = NULL;
1376 struct smbd_server_connection *sconn = req->sconn;
1377 NTTIME now = timeval_to_nttime(&req->request_time);
1378 struct smbXsrv_session *session = NULL;
1379 NTSTATUS status;
1381 errno = 0;
1383 if (smb_messages[type].fn == NULL) {
1384 DEBUG(0,("Unknown message type %d!\n",type));
1385 smb_dump("Unknown", 1, (const char *)req->inbuf);
1386 reply_unknown_new(req, type);
1387 return NULL;
1390 flags = smb_messages[type].flags;
1392 /* In share mode security we must ignore the vuid. */
1393 session_tag = req->vuid;
1394 conn = req->conn;
1396 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1397 (int)getpid(), (unsigned long)conn));
1399 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1401 /* Ensure this value is replaced in the incoming packet. */
1402 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1405 * Ensure the correct username is in current_user_info. This is a
1406 * really ugly bugfix for problems with multiple session_setup_and_X's
1407 * being done and allowing %U and %G substitutions to work correctly.
1408 * There is a reason this code is done here, don't move it unless you
1409 * know what you're doing... :-).
1410 * JRA.
1414 * lookup an existing session
1416 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1417 * here, the main check is still in change_to_user()
1419 status = smb1srv_session_lookup(sconn->conn,
1420 session_tag,
1421 now,
1422 &session);
1423 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1424 switch (type) {
1425 case SMBsesssetupX:
1426 status = NT_STATUS_OK;
1427 break;
1428 default:
1429 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1430 (unsigned long long)session_tag,
1431 (unsigned long long)req->mid));
1432 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1433 return conn;
1437 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1438 struct user_struct *vuser = NULL;
1440 sconn->smb1.sessions.last_session_tag = session_tag;
1441 if (session) {
1442 vuser = session->compat;
1444 if (vuser) {
1445 set_current_user_info(
1446 vuser->session_info->unix_info->sanitized_username,
1447 vuser->session_info->unix_info->unix_name,
1448 vuser->session_info->info->domain_name);
1452 /* Does this call need to be run as the connected user? */
1453 if (flags & AS_USER) {
1455 /* Does this call need a valid tree connection? */
1456 if (!conn) {
1458 * Amazingly, the error code depends on the command
1459 * (from Samba4).
1461 if (type == SMBntcreateX) {
1462 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1463 } else {
1464 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1466 return NULL;
1469 if (!change_to_user(conn,session_tag)) {
1470 DEBUG(0, ("Error: Could not change to user. Removing "
1471 "deferred open, mid=%llu.\n",
1472 (unsigned long long)req->mid));
1473 reply_force_doserror(req, ERRSRV, ERRbaduid);
1474 return conn;
1477 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1479 /* Does it need write permission? */
1480 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1481 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1482 return conn;
1485 /* IPC services are limited */
1486 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1487 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1488 return conn;
1490 } else {
1491 /* This call needs to be run as root */
1492 change_to_root_user();
1495 /* load service specific parameters */
1496 if (conn) {
1497 if (req->encrypted) {
1498 conn->encrypted_tid = true;
1499 /* encrypted required from now on. */
1500 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1501 } else if (ENCRYPTION_REQUIRED(conn)) {
1502 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1503 DEBUG(1,("service[%s] requires encryption"
1504 "%s ACCESS_DENIED. mid=%llu\n",
1505 lp_servicename(talloc_tos(), SNUM(conn)),
1506 smb_fn_name(type),
1507 (unsigned long long)req->mid));
1508 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 return conn;
1513 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1514 (flags & (AS_USER|DO_CHDIR)
1515 ?True:False))) {
1516 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1517 return conn;
1519 conn->num_smb_operations++;
1523 * Does this protocol need to be run as guest? (Only archane
1524 * messenger service requests have this...)
1526 if (flags & AS_GUEST) {
1527 char *raddr;
1528 bool ok;
1530 if (!change_to_guest()) {
1531 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 return conn;
1535 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1536 talloc_tos());
1537 if (raddr == NULL) {
1538 reply_nterror(req, NT_STATUS_NO_MEMORY);
1539 return conn;
1543 * Haven't we checked this in smbd_process already???
1546 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1547 sconn->remote_hostname, raddr);
1548 TALLOC_FREE(raddr);
1550 if (!ok) {
1551 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1552 return conn;
1556 smb_messages[type].fn(req);
1557 return req->conn;
1560 /****************************************************************************
1561 Construct a reply to the incoming packet.
1562 ****************************************************************************/
1564 static void construct_reply(struct smbd_server_connection *sconn,
1565 char *inbuf, int size, size_t unread_bytes,
1566 uint32_t seqnum, bool encrypted,
1567 struct smb_perfcount_data *deferred_pcd)
1569 connection_struct *conn;
1570 struct smb_request *req;
1572 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1573 smb_panic("could not allocate smb_request");
1576 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1577 encrypted, seqnum)) {
1578 exit_server_cleanly("Invalid SMB request");
1581 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1583 /* we popped this message off the queue - keep original perf data */
1584 if (deferred_pcd)
1585 req->pcd = *deferred_pcd;
1586 else {
1587 SMB_PERFCOUNT_START(&req->pcd);
1588 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1589 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1592 conn = switch_message(req->cmd, req);
1594 if (req->outbuf == NULL) {
1595 return;
1598 if (CVAL(req->outbuf,0) == 0) {
1599 show_msg((char *)req->outbuf);
1602 if (!srv_send_smb(req->sconn,
1603 (char *)req->outbuf,
1604 true, req->seqnum+1,
1605 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1606 &req->pcd)) {
1607 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1610 TALLOC_FREE(req);
1612 return;
1615 static void construct_reply_chain(struct smbd_server_connection *sconn,
1616 char *inbuf, int size, uint32_t seqnum,
1617 bool encrypted,
1618 struct smb_perfcount_data *deferred_pcd)
1620 struct smb_request **reqs = NULL;
1621 struct smb_request *req;
1622 unsigned num_reqs;
1623 bool ok;
1625 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1626 seqnum, &reqs, &num_reqs);
1627 if (!ok) {
1628 char errbuf[smb_size];
1629 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1630 __LINE__, __FILE__);
1631 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1632 NULL)) {
1633 exit_server_cleanly("construct_reply_chain: "
1634 "srv_send_smb failed.");
1636 return;
1639 req = reqs[0];
1640 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1642 req->conn = switch_message(req->cmd, req);
1644 if (req->outbuf == NULL) {
1646 * Request has suspended itself, will come
1647 * back here.
1649 return;
1651 smb_request_done(req);
1655 * To be called from an async SMB handler that is potentially chained
1656 * when it is finished for shipping.
1659 void smb_request_done(struct smb_request *req)
1661 struct smb_request **reqs = NULL;
1662 struct smb_request *first_req;
1663 size_t i, num_reqs, next_index;
1664 NTSTATUS status;
1666 if (req->chain == NULL) {
1667 first_req = req;
1668 goto shipit;
1671 reqs = req->chain;
1672 num_reqs = talloc_array_length(reqs);
1674 for (i=0; i<num_reqs; i++) {
1675 if (reqs[i] == req) {
1676 break;
1679 if (i == num_reqs) {
1681 * Invalid chain, should not happen
1683 status = NT_STATUS_INTERNAL_ERROR;
1684 goto error;
1686 next_index = i+1;
1688 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1689 struct smb_request *next = reqs[next_index];
1690 struct smbXsrv_tcon *tcon;
1691 NTTIME now = timeval_to_nttime(&req->request_time);
1693 next->vuid = SVAL(req->outbuf, smb_uid);
1694 next->tid = SVAL(req->outbuf, smb_tid);
1695 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1696 now, &tcon);
1697 if (NT_STATUS_IS_OK(status)) {
1698 req->conn = tcon->compat;
1699 } else {
1700 req->conn = NULL;
1702 next->chain_fsp = req->chain_fsp;
1703 next->inbuf = (uint8_t *)req->inbuf;
1705 req = next;
1706 req->conn = switch_message(req->cmd, req);
1708 if (req->outbuf == NULL) {
1710 * Request has suspended itself, will come
1711 * back here.
1713 return;
1715 next_index += 1;
1718 first_req = reqs[0];
1720 for (i=1; i<next_index; i++) {
1721 bool ok;
1723 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1724 if (!ok) {
1725 status = NT_STATUS_INTERNAL_ERROR;
1726 goto error;
1730 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1731 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1734 * This scary statement intends to set the
1735 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1736 * to the value last_req->outbuf carries
1738 SSVAL(first_req->outbuf, smb_flg2,
1739 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1740 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1743 * Transfer the error codes from the subrequest to the main one
1745 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1746 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1748 _smb_setlen_large(
1749 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1751 shipit:
1752 if (!srv_send_smb(first_req->sconn,
1753 (char *)first_req->outbuf,
1754 true, first_req->seqnum+1,
1755 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1756 &first_req->pcd)) {
1757 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1758 "failed.");
1760 TALLOC_FREE(req); /* non-chained case */
1761 TALLOC_FREE(reqs); /* chained case */
1762 return;
1764 error:
1766 char errbuf[smb_size];
1767 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1768 if (!srv_send_smb(req->sconn, errbuf, true,
1769 req->seqnum+1, req->encrypted,
1770 NULL)) {
1771 exit_server_cleanly("construct_reply_chain: "
1772 "srv_send_smb failed.");
1775 TALLOC_FREE(req); /* non-chained case */
1776 TALLOC_FREE(reqs); /* chained case */
1779 /****************************************************************************
1780 Process an smb from the client
1781 ****************************************************************************/
1782 static void process_smb(struct smbd_server_connection *sconn,
1783 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1784 uint32_t seqnum, bool encrypted,
1785 struct smb_perfcount_data *deferred_pcd)
1787 int msg_type = CVAL(inbuf,0);
1789 DO_PROFILE_INC(smb_count);
1791 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1792 smb_len(inbuf) ) );
1793 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1794 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1796 if (msg_type != NBSSmessage) {
1798 * NetBIOS session request, keepalive, etc.
1800 reply_special(sconn, (char *)inbuf, nread);
1801 goto done;
1804 if (sconn->using_smb2) {
1805 /* At this point we're not really using smb2,
1806 * we make the decision here.. */
1807 if (smbd_is_smb2_header(inbuf, nread)) {
1808 smbd_smb2_first_negprot(sconn, inbuf, nread);
1809 return;
1810 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1811 && CVAL(inbuf, smb_com) != 0x72) {
1812 /* This is a non-negprot SMB1 packet.
1813 Disable SMB2 from now on. */
1814 sconn->using_smb2 = false;
1818 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1819 * so subtract 4 from it. */
1820 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1821 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1822 smb_len(inbuf)));
1824 /* special magic for immediate exit */
1825 if ((nread == 9) &&
1826 (IVAL(inbuf, 4) == 0x74697865) &&
1827 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1828 uint8_t exitcode = CVAL(inbuf, 8);
1829 DEBUG(1, ("Exiting immediately with code %d\n",
1830 (int)exitcode));
1831 exit(exitcode);
1834 exit_server_cleanly("Non-SMB packet");
1837 show_msg((char *)inbuf);
1839 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1840 construct_reply_chain(sconn, (char *)inbuf, nread,
1841 seqnum, encrypted, deferred_pcd);
1842 } else {
1843 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1844 seqnum, encrypted, deferred_pcd);
1847 sconn->trans_num++;
1849 done:
1850 sconn->num_requests++;
1852 /* The timeout_processing function isn't run nearly
1853 often enough to implement 'max log size' without
1854 overrunning the size of the file by many megabytes.
1855 This is especially true if we are running at debug
1856 level 10. Checking every 50 SMBs is a nice
1857 tradeoff of performance vs log file size overrun. */
1859 if ((sconn->num_requests % 50) == 0 &&
1860 need_to_check_log_size()) {
1861 change_to_root_user();
1862 check_log_size();
1866 /****************************************************************************
1867 Return a string containing the function name of a SMB command.
1868 ****************************************************************************/
1870 const char *smb_fn_name(int type)
1872 const char *unknown_name = "SMBunknown";
1874 if (smb_messages[type].name == NULL)
1875 return(unknown_name);
1877 return(smb_messages[type].name);
1880 /****************************************************************************
1881 Helper functions for contruct_reply.
1882 ****************************************************************************/
1884 void add_to_common_flags2(uint32 v)
1886 common_flags2 |= v;
1889 void remove_from_common_flags2(uint32 v)
1891 common_flags2 &= ~v;
1894 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1895 char *outbuf)
1897 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1898 uint16_t out_flags2 = common_flags2;
1900 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1901 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1902 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1904 srv_set_message(outbuf,0,0,false);
1906 SCVAL(outbuf, smb_com, req->cmd);
1907 SIVAL(outbuf,smb_rcls,0);
1908 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1909 SSVAL(outbuf,smb_flg2, out_flags2);
1910 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1911 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1913 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1914 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1915 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1916 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1919 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1921 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1925 * @brief Find the smb_cmd offset of the last command pushed
1926 * @param[in] buf The buffer we're building up
1927 * @retval Where can we put our next andx cmd?
1929 * While chaining requests, the "next" request we're looking at needs to put
1930 * its SMB_Command before the data the previous request already built up added
1931 * to the chain. Find the offset to the place where we have to put our cmd.
1934 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1936 uint8_t cmd;
1937 size_t ofs;
1939 cmd = CVAL(buf, smb_com);
1941 if (!is_andx_req(cmd)) {
1942 return false;
1945 ofs = smb_vwv0;
1947 while (CVAL(buf, ofs) != 0xff) {
1949 if (!is_andx_req(CVAL(buf, ofs))) {
1950 return false;
1954 * ofs is from start of smb header, so add the 4 length
1955 * bytes. The next cmd is right after the wct field.
1957 ofs = SVAL(buf, ofs+2) + 4 + 1;
1959 if (ofs+4 >= talloc_get_size(buf)) {
1960 return false;
1964 *pofs = ofs;
1965 return true;
1969 * @brief Do the smb chaining at a buffer level
1970 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1971 * @param[in] andx_buf Buffer to be appended
1974 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1976 uint8_t smb_command = CVAL(andx_buf, smb_com);
1977 uint8_t wct = CVAL(andx_buf, smb_wct);
1978 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1979 uint32_t num_bytes = smb_buflen(andx_buf);
1980 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1982 uint8_t *outbuf;
1983 size_t old_size, new_size;
1984 size_t ofs;
1985 size_t chain_padding = 0;
1986 size_t andx_cmd_ofs;
1989 old_size = talloc_get_size(*poutbuf);
1991 if ((old_size % 4) != 0) {
1993 * Align the wct field of subsequent requests to a 4-byte
1994 * boundary
1996 chain_padding = 4 - (old_size % 4);
2000 * After the old request comes the new wct field (1 byte), the vwv's
2001 * and the num_bytes field.
2004 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2005 new_size += num_bytes;
2007 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2008 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2009 (unsigned)new_size));
2010 return false;
2013 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2014 if (outbuf == NULL) {
2015 DEBUG(0, ("talloc failed\n"));
2016 return false;
2018 *poutbuf = outbuf;
2020 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2021 DEBUG(1, ("invalid command chain\n"));
2022 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2023 return false;
2026 if (chain_padding != 0) {
2027 memset(outbuf + old_size, 0, chain_padding);
2028 old_size += chain_padding;
2031 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2032 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2034 ofs = old_size;
2037 * Push the chained request:
2039 * wct field
2042 SCVAL(outbuf, ofs, wct);
2043 ofs += 1;
2046 * vwv array
2049 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2052 * HACK ALERT
2054 * Read&X has an offset into its data buffer at
2055 * vwv[6]. reply_read_andx has no idea anymore that it's
2056 * running from within a chain, so we have to fix up the
2057 * offset here.
2059 * Although it looks disgusting at this place, I want to keep
2060 * it here. The alternative would be to push knowledge about
2061 * the andx chain down into read&x again.
2064 if (smb_command == SMBreadX) {
2065 uint8_t *bytes_addr;
2067 if (wct < 7) {
2069 * Invalid read&x response
2071 return false;
2074 bytes_addr = outbuf + ofs /* vwv start */
2075 + sizeof(uint16_t) * wct /* vwv array */
2076 + sizeof(uint16_t); /* bcc */
2078 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2079 bytes_addr - outbuf - 4);
2082 ofs += sizeof(uint16_t) * wct;
2085 * bcc (byte count)
2088 SSVAL(outbuf, ofs, num_bytes);
2089 ofs += sizeof(uint16_t);
2092 * The bytes field
2095 memcpy(outbuf + ofs, bytes, num_bytes);
2097 return true;
2100 bool smb1_is_chain(const uint8_t *buf)
2102 uint8_t cmd, wct, andx_cmd;
2104 cmd = CVAL(buf, smb_com);
2105 if (!is_andx_req(cmd)) {
2106 return false;
2108 wct = CVAL(buf, smb_wct);
2109 if (wct < 2) {
2110 return false;
2112 andx_cmd = CVAL(buf, smb_vwv);
2113 return (andx_cmd != 0xFF);
2116 bool smb1_walk_chain(const uint8_t *buf,
2117 bool (*fn)(uint8_t cmd,
2118 uint8_t wct, const uint16_t *vwv,
2119 uint16_t num_bytes, const uint8_t *bytes,
2120 void *private_data),
2121 void *private_data)
2123 size_t smblen = smb_len(buf);
2124 const char *smb_buf = smb_base(buf);
2125 uint8_t cmd, chain_cmd;
2126 uint8_t wct;
2127 const uint16_t *vwv;
2128 uint16_t num_bytes;
2129 const uint8_t *bytes;
2131 cmd = CVAL(buf, smb_com);
2132 wct = CVAL(buf, smb_wct);
2133 vwv = (const uint16_t *)(buf + smb_vwv);
2134 num_bytes = smb_buflen(buf);
2135 bytes = (uint8_t *)smb_buf_const(buf);
2137 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2138 return false;
2141 if (!is_andx_req(cmd)) {
2142 return true;
2144 if (wct < 2) {
2145 return false;
2148 chain_cmd = CVAL(vwv, 0);
2150 while (chain_cmd != 0xff) {
2151 uint32_t chain_offset; /* uint32_t to avoid overflow */
2152 size_t length_needed;
2153 ptrdiff_t vwv_offset;
2155 chain_offset = SVAL(vwv+1, 0);
2158 * Check if the client tries to fool us. The chain
2159 * offset needs to point beyond the current request in
2160 * the chain, it needs to strictly grow. Otherwise we
2161 * might be tricked into an endless loop always
2162 * processing the same request over and over again. We
2163 * used to assume that vwv and the byte buffer array
2164 * in a chain are always attached, but OS/2 the
2165 * Write&X/Read&X chain puts the Read&X vwv array
2166 * right behind the Write&X vwv chain. The Write&X bcc
2167 * array is put behind the Read&X vwv array. So now we
2168 * check whether the chain offset points strictly
2169 * behind the previous vwv array. req->buf points
2170 * right after the vwv array of the previous
2171 * request. See
2172 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2173 * more information.
2176 vwv_offset = ((const char *)vwv - smb_buf);
2177 if (chain_offset <= vwv_offset) {
2178 return false;
2182 * Next check: Make sure the chain offset does not
2183 * point beyond the overall smb request length.
2186 length_needed = chain_offset+1; /* wct */
2187 if (length_needed > smblen) {
2188 return false;
2192 * Now comes the pointer magic. Goal here is to set up
2193 * vwv and buf correctly again. The chain offset (the
2194 * former vwv[1]) points at the new wct field.
2197 wct = CVAL(smb_buf, chain_offset);
2199 if (is_andx_req(chain_cmd) && (wct < 2)) {
2200 return false;
2204 * Next consistency check: Make the new vwv array fits
2205 * in the overall smb request.
2208 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2209 if (length_needed > smblen) {
2210 return false;
2212 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2215 * Now grab the new byte buffer....
2218 num_bytes = SVAL(vwv+wct, 0);
2221 * .. and check that it fits.
2224 length_needed += num_bytes;
2225 if (length_needed > smblen) {
2226 return false;
2228 bytes = (const uint8_t *)(vwv+wct+1);
2230 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2231 return false;
2234 if (!is_andx_req(chain_cmd)) {
2235 return true;
2237 chain_cmd = CVAL(vwv, 0);
2239 return true;
2242 static bool smb1_chain_length_cb(uint8_t cmd,
2243 uint8_t wct, const uint16_t *vwv,
2244 uint16_t num_bytes, const uint8_t *bytes,
2245 void *private_data)
2247 unsigned *count = (unsigned *)private_data;
2248 *count += 1;
2249 return true;
2252 unsigned smb1_chain_length(const uint8_t *buf)
2254 unsigned count = 0;
2256 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2257 return 0;
2259 return count;
2262 struct smb1_parse_chain_state {
2263 TALLOC_CTX *mem_ctx;
2264 const uint8_t *buf;
2265 struct smbd_server_connection *sconn;
2266 bool encrypted;
2267 uint32_t seqnum;
2269 struct smb_request **reqs;
2270 unsigned num_reqs;
2273 static bool smb1_parse_chain_cb(uint8_t cmd,
2274 uint8_t wct, const uint16_t *vwv,
2275 uint16_t num_bytes, const uint8_t *bytes,
2276 void *private_data)
2278 struct smb1_parse_chain_state *state =
2279 (struct smb1_parse_chain_state *)private_data;
2280 struct smb_request **reqs;
2281 struct smb_request *req;
2282 bool ok;
2284 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2285 struct smb_request *, state->num_reqs+1);
2286 if (reqs == NULL) {
2287 return false;
2289 state->reqs = reqs;
2291 req = talloc(reqs, struct smb_request);
2292 if (req == NULL) {
2293 return false;
2296 ok = init_smb_request(req, state->sconn, state->buf, 0,
2297 state->encrypted, state->seqnum);
2298 if (!ok) {
2299 return false;
2301 req->cmd = cmd;
2302 req->wct = wct;
2303 req->vwv = vwv;
2304 req->buflen = num_bytes;
2305 req->buf = bytes;
2307 reqs[state->num_reqs] = req;
2308 state->num_reqs += 1;
2309 return true;
2312 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2313 struct smbd_server_connection *sconn,
2314 bool encrypted, uint32_t seqnum,
2315 struct smb_request ***reqs, unsigned *num_reqs)
2317 struct smb1_parse_chain_state state;
2318 unsigned i;
2320 state.mem_ctx = mem_ctx;
2321 state.buf = buf;
2322 state.sconn = sconn;
2323 state.encrypted = encrypted;
2324 state.seqnum = seqnum;
2325 state.reqs = NULL;
2326 state.num_reqs = 0;
2328 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2329 TALLOC_FREE(state.reqs);
2330 return false;
2332 for (i=0; i<state.num_reqs; i++) {
2333 state.reqs[i]->chain = state.reqs;
2335 *reqs = state.reqs;
2336 *num_reqs = state.num_reqs;
2337 return true;
2340 /****************************************************************************
2341 Check if services need reloading.
2342 ****************************************************************************/
2344 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2347 if (last_smb_conf_reload_time == 0) {
2348 last_smb_conf_reload_time = t;
2351 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2352 reload_services(sconn, conn_snum_used, true);
2353 last_smb_conf_reload_time = t;
2357 static bool fd_is_readable(int fd)
2359 int ret, revents;
2361 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2363 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2367 static void smbd_server_connection_write_handler(
2368 struct smbd_server_connection *sconn)
2370 /* TODO: make write nonblocking */
2373 static void smbd_server_connection_read_handler(
2374 struct smbd_server_connection *sconn, int fd)
2376 uint8_t *inbuf = NULL;
2377 size_t inbuf_len = 0;
2378 size_t unread_bytes = 0;
2379 bool encrypted = false;
2380 TALLOC_CTX *mem_ctx = talloc_tos();
2381 NTSTATUS status;
2382 uint32_t seqnum;
2384 bool from_client;
2386 if (lp_async_smb_echo_handler()
2387 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2389 * This is the super-ugly hack to prefer the packets
2390 * forwarded by the echo handler over the ones by the
2391 * client directly
2393 fd = sconn->smb1.echo_handler.trusted_fd;
2396 from_client = (sconn->sock == fd);
2398 if (from_client) {
2399 smbd_lock_socket(sconn);
2401 if (!fd_is_readable(fd)) {
2402 DEBUG(10,("the echo listener was faster\n"));
2403 smbd_unlock_socket(sconn);
2404 return;
2408 /* TODO: make this completely nonblocking */
2409 status = receive_smb_talloc(mem_ctx, sconn, fd,
2410 (char **)(void *)&inbuf,
2411 0, /* timeout */
2412 &unread_bytes,
2413 &encrypted,
2414 &inbuf_len, &seqnum,
2415 false /* trusted channel */);
2417 if (from_client) {
2418 smbd_unlock_socket(sconn);
2421 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2422 goto process;
2424 if (NT_STATUS_IS_ERR(status)) {
2425 exit_server_cleanly("failed to receive smb request");
2427 if (!NT_STATUS_IS_OK(status)) {
2428 return;
2431 process:
2432 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2433 seqnum, encrypted, NULL);
2436 static void smbd_server_connection_handler(struct tevent_context *ev,
2437 struct tevent_fd *fde,
2438 uint16_t flags,
2439 void *private_data)
2441 struct smbd_server_connection *conn = talloc_get_type(private_data,
2442 struct smbd_server_connection);
2444 if (flags & TEVENT_FD_WRITE) {
2445 smbd_server_connection_write_handler(conn);
2446 return;
2448 if (flags & TEVENT_FD_READ) {
2449 smbd_server_connection_read_handler(conn, conn->sock);
2450 return;
2454 static void smbd_server_echo_handler(struct tevent_context *ev,
2455 struct tevent_fd *fde,
2456 uint16_t flags,
2457 void *private_data)
2459 struct smbd_server_connection *conn = talloc_get_type(private_data,
2460 struct smbd_server_connection);
2462 if (flags & TEVENT_FD_WRITE) {
2463 smbd_server_connection_write_handler(conn);
2464 return;
2466 if (flags & TEVENT_FD_READ) {
2467 smbd_server_connection_read_handler(
2468 conn, conn->smb1.echo_handler.trusted_fd);
2469 return;
2473 #ifdef CLUSTER_SUPPORT
2475 struct smbd_release_ip_state {
2476 struct smbd_server_connection *sconn;
2477 char addr[INET6_ADDRSTRLEN];
2480 /****************************************************************************
2481 received when we should release a specific IP
2482 ****************************************************************************/
2483 static void release_ip(const char *ip, void *priv)
2485 struct smbd_release_ip_state *state =
2486 talloc_get_type_abort(priv,
2487 struct smbd_release_ip_state);
2488 const char *addr = state->addr;
2489 const char *p = addr;
2491 if (strncmp("::ffff:", addr, 7) == 0) {
2492 p = addr + 7;
2495 DEBUG(10, ("Got release IP message for %s, "
2496 "our address is %s\n", ip, p));
2498 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2499 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2500 ip));
2502 * With SMB2 we should do a clean disconnect,
2503 * the previous_session_id in the session setup
2504 * will cleanup the old session, tcons and opens.
2506 * A clean disconnect is needed in order to support
2507 * durable handles.
2509 * Note: typically this is never triggered
2510 * as we got a TCP RST (triggered by ctdb event scripts)
2511 * before we get CTDB_SRVID_RELEASE_IP.
2513 * We used to call _exit(1) here, but as this was mostly never
2514 * triggered and has implication on our process model,
2515 * we can just use smbd_server_connection_terminate()
2516 * (also for SMB1).
2518 smbd_server_connection_terminate(state->sconn,
2519 "CTDB_SRVID_RELEASE_IP");
2520 return;
2524 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2525 struct sockaddr_storage *srv,
2526 struct sockaddr_storage *clnt)
2528 struct smbd_release_ip_state *state;
2529 struct ctdbd_connection *cconn;
2531 cconn = messaging_ctdbd_connection();
2532 if (cconn == NULL) {
2533 return NT_STATUS_NO_MEMORY;
2536 state = talloc_zero(sconn, struct smbd_release_ip_state);
2537 if (state == NULL) {
2538 return NT_STATUS_NO_MEMORY;
2540 state->sconn = sconn;
2541 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2542 return NT_STATUS_NO_MEMORY;
2545 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2548 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2549 struct sockaddr_storage *client)
2551 socklen_t length;
2552 length = sizeof(*server);
2553 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2554 return -1;
2556 length = sizeof(*client);
2557 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2558 return -1;
2560 return 0;
2562 #endif
2565 * Send keepalive packets to our client
2567 static bool keepalive_fn(const struct timeval *now, void *private_data)
2569 struct smbd_server_connection *sconn = talloc_get_type_abort(
2570 private_data, struct smbd_server_connection);
2571 bool ret;
2573 if (sconn->using_smb2) {
2574 /* Don't do keepalives on an SMB2 connection. */
2575 return false;
2578 smbd_lock_socket(sconn);
2579 ret = send_keepalive(sconn->sock);
2580 smbd_unlock_socket(sconn);
2582 if (!ret) {
2583 char addr[INET6_ADDRSTRLEN];
2585 * Try and give an error message saying what
2586 * client failed.
2588 DEBUG(0, ("send_keepalive failed for client %s. "
2589 "Error %s - exiting\n",
2590 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2591 strerror(errno)));
2592 return False;
2594 return True;
2598 * Do the recurring check if we're idle
2600 static bool deadtime_fn(const struct timeval *now, void *private_data)
2602 struct smbd_server_connection *sconn =
2603 (struct smbd_server_connection *)private_data;
2605 if ((conn_num_open(sconn) == 0)
2606 || (conn_idle_all(sconn, now->tv_sec))) {
2607 DEBUG( 2, ( "Closing idle connection\n" ) );
2608 messaging_send(sconn->msg_ctx,
2609 messaging_server_id(sconn->msg_ctx),
2610 MSG_SHUTDOWN, &data_blob_null);
2611 return False;
2614 return True;
2618 * Do the recurring log file and smb.conf reload checks.
2621 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2623 struct smbd_server_connection *sconn = talloc_get_type_abort(
2624 private_data, struct smbd_server_connection);
2626 DEBUG(5, ("housekeeping\n"));
2628 change_to_root_user();
2630 /* update printer queue caches if necessary */
2631 update_monitored_printq_cache(sconn->msg_ctx);
2633 /* check if we need to reload services */
2634 check_reload(sconn, time_mono(NULL));
2637 * Force a log file check.
2639 force_check_log_size();
2640 check_log_size();
2641 return true;
2645 * Read an smb packet in the echo handler child, giving the parent
2646 * smbd one second to react once the socket becomes readable.
2649 struct smbd_echo_read_state {
2650 struct tevent_context *ev;
2651 struct smbd_server_connection *sconn;
2653 char *buf;
2654 size_t buflen;
2655 uint32_t seqnum;
2658 static void smbd_echo_read_readable(struct tevent_req *subreq);
2659 static void smbd_echo_read_waited(struct tevent_req *subreq);
2661 static struct tevent_req *smbd_echo_read_send(
2662 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2663 struct smbd_server_connection *sconn)
2665 struct tevent_req *req, *subreq;
2666 struct smbd_echo_read_state *state;
2668 req = tevent_req_create(mem_ctx, &state,
2669 struct smbd_echo_read_state);
2670 if (req == NULL) {
2671 return NULL;
2673 state->ev = ev;
2674 state->sconn = sconn;
2676 subreq = wait_for_read_send(state, ev, sconn->sock);
2677 if (tevent_req_nomem(subreq, req)) {
2678 return tevent_req_post(req, ev);
2680 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2681 return req;
2684 static void smbd_echo_read_readable(struct tevent_req *subreq)
2686 struct tevent_req *req = tevent_req_callback_data(
2687 subreq, struct tevent_req);
2688 struct smbd_echo_read_state *state = tevent_req_data(
2689 req, struct smbd_echo_read_state);
2690 bool ok;
2691 int err;
2693 ok = wait_for_read_recv(subreq, &err);
2694 TALLOC_FREE(subreq);
2695 if (!ok) {
2696 tevent_req_nterror(req, map_nt_error_from_unix(err));
2697 return;
2701 * Give the parent smbd one second to step in
2704 subreq = tevent_wakeup_send(
2705 state, state->ev, timeval_current_ofs(1, 0));
2706 if (tevent_req_nomem(subreq, req)) {
2707 return;
2709 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2712 static void smbd_echo_read_waited(struct tevent_req *subreq)
2714 struct tevent_req *req = tevent_req_callback_data(
2715 subreq, struct tevent_req);
2716 struct smbd_echo_read_state *state = tevent_req_data(
2717 req, struct smbd_echo_read_state);
2718 struct smbd_server_connection *sconn = state->sconn;
2719 bool ok;
2720 NTSTATUS status;
2721 size_t unread = 0;
2722 bool encrypted;
2724 ok = tevent_wakeup_recv(subreq);
2725 TALLOC_FREE(subreq);
2726 if (!ok) {
2727 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2728 return;
2731 ok = smbd_lock_socket_internal(sconn);
2732 if (!ok) {
2733 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2734 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2735 return;
2738 if (!fd_is_readable(sconn->sock)) {
2739 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2740 (int)getpid()));
2742 ok = smbd_unlock_socket_internal(sconn);
2743 if (!ok) {
2744 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2745 DEBUG(1, ("%s: failed to unlock socket\n",
2746 __location__));
2747 return;
2750 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2751 if (tevent_req_nomem(subreq, req)) {
2752 return;
2754 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2755 return;
2758 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2759 0 /* timeout */,
2760 &unread,
2761 &encrypted,
2762 &state->buflen,
2763 &state->seqnum,
2764 false /* trusted_channel*/);
2766 if (tevent_req_nterror(req, status)) {
2767 tevent_req_nterror(req, status);
2768 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2769 (int)getpid(), nt_errstr(status)));
2770 return;
2773 ok = smbd_unlock_socket_internal(sconn);
2774 if (!ok) {
2775 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2776 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2777 return;
2779 tevent_req_done(req);
2782 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2783 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2785 struct smbd_echo_read_state *state = tevent_req_data(
2786 req, struct smbd_echo_read_state);
2787 NTSTATUS status;
2789 if (tevent_req_is_nterror(req, &status)) {
2790 return status;
2792 *pbuf = talloc_move(mem_ctx, &state->buf);
2793 *pbuflen = state->buflen;
2794 *pseqnum = state->seqnum;
2795 return NT_STATUS_OK;
2798 struct smbd_echo_state {
2799 struct tevent_context *ev;
2800 struct iovec *pending;
2801 struct smbd_server_connection *sconn;
2802 int parent_pipe;
2804 struct tevent_fd *parent_fde;
2806 struct tevent_req *write_req;
2809 static void smbd_echo_writer_done(struct tevent_req *req);
2811 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2813 int num_pending;
2815 if (state->write_req != NULL) {
2816 return;
2819 num_pending = talloc_array_length(state->pending);
2820 if (num_pending == 0) {
2821 return;
2824 state->write_req = writev_send(state, state->ev, NULL,
2825 state->parent_pipe, false,
2826 state->pending, num_pending);
2827 if (state->write_req == NULL) {
2828 DEBUG(1, ("writev_send failed\n"));
2829 exit(1);
2832 talloc_steal(state->write_req, state->pending);
2833 state->pending = NULL;
2835 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2836 state);
2839 static void smbd_echo_writer_done(struct tevent_req *req)
2841 struct smbd_echo_state *state = tevent_req_callback_data(
2842 req, struct smbd_echo_state);
2843 ssize_t written;
2844 int err;
2846 written = writev_recv(req, &err);
2847 TALLOC_FREE(req);
2848 state->write_req = NULL;
2849 if (written == -1) {
2850 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2851 exit(1);
2853 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2854 smbd_echo_activate_writer(state);
2857 static bool smbd_echo_reply(struct smbd_echo_state *state,
2858 uint8_t *inbuf, size_t inbuf_len,
2859 uint32_t seqnum)
2861 struct smb_request req;
2862 uint16_t num_replies;
2863 char *outbuf;
2864 bool ok;
2866 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2867 DEBUG(10, ("Got netbios keepalive\n"));
2869 * Just swallow it
2871 return true;
2874 if (inbuf_len < smb_size) {
2875 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2876 return false;
2878 if (!valid_smb_header(state->sconn, inbuf)) {
2879 DEBUG(10, ("Got invalid SMB header\n"));
2880 return false;
2883 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2884 seqnum)) {
2885 return false;
2887 req.inbuf = inbuf;
2889 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2890 smb_messages[req.cmd].name
2891 ? smb_messages[req.cmd].name : "unknown"));
2893 if (req.cmd != SMBecho) {
2894 return false;
2896 if (req.wct < 1) {
2897 return false;
2900 num_replies = SVAL(req.vwv+0, 0);
2901 if (num_replies != 1) {
2902 /* Not a Windows "Hey, you're still there?" request */
2903 return false;
2906 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2907 1, req.buflen)) {
2908 DEBUG(10, ("create_outbuf failed\n"));
2909 return false;
2911 req.outbuf = (uint8_t *)outbuf;
2913 SSVAL(req.outbuf, smb_vwv0, num_replies);
2915 if (req.buflen > 0) {
2916 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2919 ok = srv_send_smb(req.sconn,
2920 (char *)outbuf,
2921 true, seqnum+1,
2922 false, &req.pcd);
2923 TALLOC_FREE(outbuf);
2924 if (!ok) {
2925 exit(1);
2928 return true;
2931 static void smbd_echo_exit(struct tevent_context *ev,
2932 struct tevent_fd *fde, uint16_t flags,
2933 void *private_data)
2935 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2936 exit(0);
2939 static void smbd_echo_got_packet(struct tevent_req *req);
2941 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2942 int parent_pipe)
2944 struct smbd_echo_state *state;
2945 struct tevent_req *read_req;
2947 state = talloc_zero(sconn, struct smbd_echo_state);
2948 if (state == NULL) {
2949 DEBUG(1, ("talloc failed\n"));
2950 return;
2952 state->sconn = sconn;
2953 state->parent_pipe = parent_pipe;
2954 state->ev = s3_tevent_context_init(state);
2955 if (state->ev == NULL) {
2956 DEBUG(1, ("tevent_context_init failed\n"));
2957 TALLOC_FREE(state);
2958 return;
2960 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2961 TEVENT_FD_READ, smbd_echo_exit,
2962 state);
2963 if (state->parent_fde == NULL) {
2964 DEBUG(1, ("tevent_add_fd failed\n"));
2965 TALLOC_FREE(state);
2966 return;
2969 read_req = smbd_echo_read_send(state, state->ev, sconn);
2970 if (read_req == NULL) {
2971 DEBUG(1, ("smbd_echo_read_send failed\n"));
2972 TALLOC_FREE(state);
2973 return;
2975 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2977 while (true) {
2978 if (tevent_loop_once(state->ev) == -1) {
2979 DEBUG(1, ("tevent_loop_once failed: %s\n",
2980 strerror(errno)));
2981 break;
2984 TALLOC_FREE(state);
2987 static void smbd_echo_got_packet(struct tevent_req *req)
2989 struct smbd_echo_state *state = tevent_req_callback_data(
2990 req, struct smbd_echo_state);
2991 NTSTATUS status;
2992 char *buf = NULL;
2993 size_t buflen = 0;
2994 uint32_t seqnum = 0;
2995 bool reply;
2997 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2998 TALLOC_FREE(req);
2999 if (!NT_STATUS_IS_OK(status)) {
3000 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3001 nt_errstr(status)));
3002 exit(1);
3005 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3006 if (!reply) {
3007 size_t num_pending;
3008 struct iovec *tmp;
3009 struct iovec *iov;
3011 num_pending = talloc_array_length(state->pending);
3012 tmp = talloc_realloc(state, state->pending, struct iovec,
3013 num_pending+1);
3014 if (tmp == NULL) {
3015 DEBUG(1, ("talloc_realloc failed\n"));
3016 exit(1);
3018 state->pending = tmp;
3020 if (buflen >= smb_size) {
3022 * place the seqnum in the packet so that the main process
3023 * can reply with signing
3025 SIVAL(buf, smb_ss_field, seqnum);
3026 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3029 iov = &state->pending[num_pending];
3030 iov->iov_base = talloc_move(state->pending, &buf);
3031 iov->iov_len = buflen;
3033 DEBUG(10,("echo_handler[%d]: forward to main\n",
3034 (int)getpid()));
3035 smbd_echo_activate_writer(state);
3038 req = smbd_echo_read_send(state, state->ev, state->sconn);
3039 if (req == NULL) {
3040 DEBUG(1, ("smbd_echo_read_send failed\n"));
3041 exit(1);
3043 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3048 * Handle SMBecho requests in a forked child process
3050 bool fork_echo_handler(struct smbd_server_connection *sconn)
3052 int listener_pipe[2];
3053 int res;
3054 pid_t child;
3056 res = pipe(listener_pipe);
3057 if (res == -1) {
3058 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3059 return false;
3061 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3062 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3063 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3064 goto fail;
3067 child = fork();
3068 if (child == 0) {
3069 NTSTATUS status;
3071 close(listener_pipe[0]);
3072 set_blocking(listener_pipe[1], false);
3074 status = reinit_after_fork(sconn->msg_ctx,
3075 sconn->ev_ctx,
3076 true);
3077 if (!NT_STATUS_IS_OK(status)) {
3078 DEBUG(1, ("reinit_after_fork failed: %s\n",
3079 nt_errstr(status)));
3080 exit(1);
3082 smbd_echo_loop(sconn, listener_pipe[1]);
3083 exit(0);
3085 close(listener_pipe[1]);
3086 listener_pipe[1] = -1;
3087 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3089 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3092 * Without smb signing this is the same as the normal smbd
3093 * listener. This needs to change once signing comes in.
3095 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3096 sconn,
3097 sconn->smb1.echo_handler.trusted_fd,
3098 TEVENT_FD_READ,
3099 smbd_server_echo_handler,
3100 sconn);
3101 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3102 DEBUG(1, ("event_add_fd failed\n"));
3103 goto fail;
3106 return true;
3108 fail:
3109 if (listener_pipe[0] != -1) {
3110 close(listener_pipe[0]);
3112 if (listener_pipe[1] != -1) {
3113 close(listener_pipe[1]);
3115 sconn->smb1.echo_handler.trusted_fd = -1;
3116 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3117 close(sconn->smb1.echo_handler.socket_lock_fd);
3119 sconn->smb1.echo_handler.trusted_fd = -1;
3120 sconn->smb1.echo_handler.socket_lock_fd = -1;
3121 return false;
3124 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3126 while (user) {
3127 if (user->session_info &&
3128 (user->session_info->unix_token->uid == uid)) {
3129 return true;
3131 user = user->next;
3133 return false;
3136 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3138 while (user) {
3139 if (user->session_info != NULL) {
3140 int i;
3141 struct security_unix_token *utok;
3143 utok = user->session_info->unix_token;
3144 if (utok->gid == gid) {
3145 return true;
3147 for(i=0; i<utok->ngroups; i++) {
3148 if (utok->groups[i] == gid) {
3149 return true;
3153 user = user->next;
3155 return false;
3158 static bool sid_in_use(const struct user_struct *user,
3159 const struct dom_sid *psid)
3161 while (user) {
3162 struct security_token *tok;
3164 if (user->session_info == NULL) {
3165 continue;
3167 tok = user->session_info->security_token;
3168 if (tok == NULL) {
3170 * Not sure session_info->security_token can
3171 * ever be NULL. This check might be not
3172 * necessary.
3174 continue;
3176 if (security_token_has_sid(tok, psid)) {
3177 return true;
3179 user = user->next;
3181 return false;
3184 static bool id_in_use(const struct user_struct *user,
3185 const struct id_cache_ref *id)
3187 switch(id->type) {
3188 case UID:
3189 return uid_in_use(user, id->id.uid);
3190 case GID:
3191 return gid_in_use(user, id->id.gid);
3192 case SID:
3193 return sid_in_use(user, &id->id.sid);
3194 default:
3195 break;
3197 return false;
3200 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3201 void *private_data,
3202 uint32_t msg_type,
3203 struct server_id server_id,
3204 DATA_BLOB* data)
3206 const char *msg = (data && data->data)
3207 ? (const char *)data->data : "<NULL>";
3208 struct id_cache_ref id;
3209 struct smbd_server_connection *sconn =
3210 talloc_get_type_abort(private_data,
3211 struct smbd_server_connection);
3213 if (!id_cache_ref_parse(msg, &id)) {
3214 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3215 return;
3218 if (id_in_use(sconn->users, &id)) {
3219 exit_server_cleanly(msg);
3221 id_cache_delete_from_cache(&id);
3224 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3225 enum protocol_types protocol)
3227 NTSTATUS status;
3229 set_Protocol(protocol);
3230 conn->protocol = protocol;
3232 if (protocol >= PROTOCOL_SMB2_02) {
3233 status = smb2srv_session_table_init(conn);
3234 if (!NT_STATUS_IS_OK(status)) {
3235 return status;
3238 status = smb2srv_open_table_init(conn);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 return status;
3242 } else {
3243 status = smb1srv_session_table_init(conn);
3244 if (!NT_STATUS_IS_OK(status)) {
3245 return status;
3248 status = smb1srv_tcon_table_init(conn);
3249 if (!NT_STATUS_IS_OK(status)) {
3250 return status;
3253 status = smb1srv_open_table_init(conn);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 return status;
3259 return NT_STATUS_OK;
3262 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3263 void *private_data)
3265 struct smbXsrv_connection *conn =
3266 talloc_get_type_abort(private_data,
3267 struct smbXsrv_connection);
3269 switch (point) {
3270 case TEVENT_TRACE_BEFORE_WAIT:
3272 * This just removes compiler warning
3273 * without profile support
3275 conn->smbd_idle_profstamp = 0;
3276 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3277 break;
3278 case TEVENT_TRACE_AFTER_WAIT:
3279 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3280 break;
3284 /****************************************************************************
3285 Process commands from the client
3286 ****************************************************************************/
3288 void smbd_process(struct tevent_context *ev_ctx,
3289 struct messaging_context *msg_ctx,
3290 int sock_fd,
3291 bool interactive)
3293 TALLOC_CTX *frame = talloc_stackframe();
3294 struct smbXsrv_connection *conn;
3295 struct smbd_server_connection *sconn;
3296 struct sockaddr_storage ss;
3297 struct sockaddr *sa = NULL;
3298 socklen_t sa_socklen;
3299 struct tsocket_address *local_address = NULL;
3300 struct tsocket_address *remote_address = NULL;
3301 const char *locaddr = NULL;
3302 const char *remaddr = NULL;
3303 char *rhost;
3304 int ret;
3306 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3307 if (conn == NULL) {
3308 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3309 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3312 conn->ev_ctx = ev_ctx;
3313 conn->msg_ctx = msg_ctx;
3315 sconn = talloc_zero(conn, struct smbd_server_connection);
3316 if (!sconn) {
3317 exit_server("failed to create smbd_server_connection");
3320 conn->sconn = sconn;
3321 sconn->conn = conn;
3324 * TODO: remove this...:-)
3326 global_smbXsrv_connection = conn;
3328 sconn->ev_ctx = ev_ctx;
3329 sconn->msg_ctx = msg_ctx;
3330 sconn->sock = sock_fd;
3331 sconn->smb1.echo_handler.trusted_fd = -1;
3332 sconn->smb1.echo_handler.socket_lock_fd = -1;
3334 if (!interactive) {
3335 smbd_setup_sig_term_handler(sconn);
3336 smbd_setup_sig_hup_handler(sconn);
3338 if (!serverid_register(messaging_server_id(msg_ctx),
3339 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3340 |FLAG_MSG_DBWRAP
3341 |FLAG_MSG_PRINT_GENERAL)) {
3342 exit_server_cleanly("Could not register myself in "
3343 "serverid.tdb");
3347 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3349 * We're not making the decision here,
3350 * we're just allowing the client
3351 * to decide between SMB1 and SMB2
3352 * with the first negprot
3353 * packet.
3355 sconn->using_smb2 = true;
3358 /* Ensure child is set to blocking mode */
3359 set_blocking(sconn->sock,True);
3361 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3362 set_socket_options(sconn->sock, lp_socket_options());
3364 sa = (struct sockaddr *)(void *)&ss;
3365 sa_socklen = sizeof(ss);
3366 ret = getpeername(sconn->sock, sa, &sa_socklen);
3367 if (ret != 0) {
3368 int level = (errno == ENOTCONN)?2:0;
3369 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3370 exit_server_cleanly("getpeername() failed.\n");
3372 ret = tsocket_address_bsd_from_sockaddr(sconn,
3373 sa, sa_socklen,
3374 &remote_address);
3375 if (ret != 0) {
3376 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3377 __location__, strerror(errno)));
3378 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3381 sa = (struct sockaddr *)(void *)&ss;
3382 sa_socklen = sizeof(ss);
3383 ret = getsockname(sconn->sock, sa, &sa_socklen);
3384 if (ret != 0) {
3385 int level = (errno == ENOTCONN)?2:0;
3386 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3387 exit_server_cleanly("getsockname() failed.\n");
3389 ret = tsocket_address_bsd_from_sockaddr(sconn,
3390 sa, sa_socklen,
3391 &local_address);
3392 if (ret != 0) {
3393 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3394 __location__, strerror(errno)));
3395 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3398 sconn->local_address = local_address;
3399 sconn->remote_address = remote_address;
3401 if (tsocket_address_is_inet(local_address, "ip")) {
3402 locaddr = tsocket_address_inet_addr_string(
3403 sconn->local_address,
3404 talloc_tos());
3405 if (locaddr == NULL) {
3406 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3407 __location__, strerror(errno)));
3408 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3410 } else {
3411 locaddr = "0.0.0.0";
3414 if (tsocket_address_is_inet(remote_address, "ip")) {
3415 remaddr = tsocket_address_inet_addr_string(
3416 sconn->remote_address,
3417 talloc_tos());
3418 if (remaddr == NULL) {
3419 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3420 __location__, strerror(errno)));
3421 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3423 } else {
3424 remaddr = "0.0.0.0";
3427 /* this is needed so that we get decent entries
3428 in smbstatus for port 445 connects */
3429 set_remote_machine_name(remaddr, false);
3430 reload_services(sconn, conn_snum_used, true);
3433 * Before the first packet, check the global hosts allow/ hosts deny
3434 * parameters before doing any parsing of packets passed to us by the
3435 * client. This prevents attacks on our parsing code from hosts not in
3436 * the hosts allow list.
3439 ret = get_remote_hostname(remote_address,
3440 &rhost,
3441 talloc_tos());
3442 if (ret < 0) {
3443 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3444 __location__, strerror(errno)));
3445 exit_server_cleanly("get_remote_hostname failed.\n");
3447 if (strequal(rhost, "UNKNOWN")) {
3448 rhost = talloc_strdup(talloc_tos(), remaddr);
3450 sconn->remote_hostname = talloc_move(sconn, &rhost);
3452 sub_set_socket_ids(remaddr,
3453 sconn->remote_hostname,
3454 locaddr);
3456 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3457 sconn->remote_hostname,
3458 remaddr)) {
3460 * send a negative session response "not listening on calling
3461 * name"
3463 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3464 DEBUG( 1, ("Connection denied from %s to %s\n",
3465 tsocket_address_string(remote_address, talloc_tos()),
3466 tsocket_address_string(local_address, talloc_tos())));
3467 (void)srv_send_smb(sconn,(char *)buf, false,
3468 0, false, NULL);
3469 exit_server_cleanly("connection denied");
3472 DEBUG(10, ("Connection allowed from %s to %s\n",
3473 tsocket_address_string(remote_address, talloc_tos()),
3474 tsocket_address_string(local_address, talloc_tos())));
3476 if (lp_preload_modules()) {
3477 smb_load_modules(lp_preload_modules());
3480 smb_perfcount_init();
3482 if (!init_account_policy()) {
3483 exit_server("Could not open account policy tdb.\n");
3486 if (*lp_rootdir(talloc_tos())) {
3487 if (chroot(lp_rootdir(talloc_tos())) != 0) {
3488 DEBUG(0,("Failed to change root to %s\n",
3489 lp_rootdir(talloc_tos())));
3490 exit_server("Failed to chroot()");
3492 if (chdir("/") == -1) {
3493 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
3494 exit_server("Failed to chroot()");
3496 DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
3499 if (!srv_init_signing(sconn)) {
3500 exit_server("Failed to init smb_signing");
3503 if (!file_init(sconn)) {
3504 exit_server("file_init() failed");
3507 /* Setup oplocks */
3508 if (!init_oplocks(sconn))
3509 exit_server("Failed to init oplocks");
3511 /* register our message handlers */
3512 messaging_register(sconn->msg_ctx, sconn,
3513 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3514 messaging_register(sconn->msg_ctx, sconn,
3515 MSG_SMB_CLOSE_FILE, msg_close_file);
3516 messaging_register(sconn->msg_ctx, sconn,
3517 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3519 id_cache_register_msgs(sconn->msg_ctx);
3520 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3521 messaging_register(sconn->msg_ctx, sconn,
3522 ID_CACHE_KILL, smbd_id_cache_kill);
3524 messaging_deregister(sconn->msg_ctx,
3525 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3526 messaging_register(sconn->msg_ctx, sconn,
3527 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3530 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3531 * MSGs to all child processes
3533 messaging_deregister(sconn->msg_ctx,
3534 MSG_DEBUG, NULL);
3535 messaging_register(sconn->msg_ctx, NULL,
3536 MSG_DEBUG, debug_message);
3538 if ((lp_keepalive() != 0)
3539 && !(event_add_idle(ev_ctx, NULL,
3540 timeval_set(lp_keepalive(), 0),
3541 "keepalive", keepalive_fn,
3542 sconn))) {
3543 DEBUG(0, ("Could not add keepalive event\n"));
3544 exit(1);
3547 if (!(event_add_idle(ev_ctx, NULL,
3548 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3549 "deadtime", deadtime_fn, sconn))) {
3550 DEBUG(0, ("Could not add deadtime event\n"));
3551 exit(1);
3554 if (!(event_add_idle(ev_ctx, NULL,
3555 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3556 "housekeeping", housekeeping_fn, sconn))) {
3557 DEBUG(0, ("Could not add housekeeping event\n"));
3558 exit(1);
3561 #ifdef CLUSTER_SUPPORT
3563 if (lp_clustering()) {
3565 * We need to tell ctdb about our client's TCP
3566 * connection, so that for failover ctdbd can send
3567 * tickle acks, triggering a reconnection by the
3568 * client.
3571 struct sockaddr_storage srv, clnt;
3573 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3574 NTSTATUS status;
3575 status = smbd_register_ips(sconn, &srv, &clnt);
3576 if (!NT_STATUS_IS_OK(status)) {
3577 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3578 nt_errstr(status)));
3580 } else
3582 DEBUG(0,("Unable to get tcp info for "
3583 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3584 strerror(errno)));
3588 #endif
3590 sconn->nbt.got_session = false;
3592 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3594 sconn->smb1.sessions.done_sesssetup = false;
3595 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3596 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3598 if (!init_dptrs(sconn)) {
3599 exit_server("init_dptrs() failed");
3602 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3603 sconn,
3604 sconn->sock,
3605 TEVENT_FD_READ,
3606 smbd_server_connection_handler,
3607 sconn);
3608 if (!sconn->smb1.fde) {
3609 exit_server("failed to create smbd_server_connection fde");
3612 sconn->conn->local_address = sconn->local_address;
3613 sconn->conn->remote_address = sconn->remote_address;
3614 sconn->conn->remote_hostname = sconn->remote_hostname;
3615 sconn->conn->protocol = PROTOCOL_NONE;
3617 TALLOC_FREE(frame);
3619 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3621 while (True) {
3622 frame = talloc_stackframe_pool(8192);
3624 errno = 0;
3625 if (tevent_loop_once(ev_ctx) == -1) {
3626 if (errno != EINTR) {
3627 DEBUG(3, ("tevent_loop_once failed: %s,"
3628 " exiting\n", strerror(errno) ));
3629 break;
3633 TALLOC_FREE(frame);
3636 exit_server_cleanly(NULL);
3639 bool req_is_in_chain(const struct smb_request *req)
3641 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3643 * We're right now handling a subsequent request, so we must
3644 * be in a chain
3646 return true;
3649 if (!is_andx_req(req->cmd)) {
3650 return false;
3653 if (req->wct < 2) {
3655 * Okay, an illegal request, but definitely not chained :-)
3657 return false;
3660 return (CVAL(req->vwv+0, 0) != 0xFF);