s3:lib: only loop over the server_ids we need to verify in serverids_exist()
[Samba/vl.git] / source3 / smbd / process.c
blobfd2c6a4b4a88d14b1453b4e5f9cb020a904f027d
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 timed_event *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 for 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(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 event_context *ev,
585 struct timed_event *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 timed_event *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)
1274 * Protect against integer wrap
1276 if ((num_bytes > 0xffffff)
1277 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1278 char *msg;
1279 if (asprintf(&msg, "num_bytes too large: %u",
1280 (unsigned)num_bytes) == -1) {
1281 msg = discard_const_p(char, "num_bytes too large");
1283 smb_panic(msg);
1286 *outbuf = talloc_array(mem_ctx, char,
1287 smb_size + num_words*2 + num_bytes);
1288 if (*outbuf == NULL) {
1289 return false;
1292 construct_reply_common(req, inbuf, *outbuf);
1293 srv_set_message(*outbuf, num_words, num_bytes, false);
1295 * Zero out the word area, the caller has to take care of the bcc area
1296 * himself
1298 if (num_words != 0) {
1299 memset(*outbuf + smb_vwv0, 0, num_words*2);
1302 return true;
1305 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1307 char *outbuf;
1308 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1309 num_bytes)) {
1310 smb_panic("could not allocate output buffer\n");
1312 req->outbuf = (uint8_t *)outbuf;
1316 /*******************************************************************
1317 Dump a packet to a file.
1318 ********************************************************************/
1320 static void smb_dump(const char *name, int type, const char *data)
1322 size_t len;
1323 int fd, i;
1324 char *fname = NULL;
1325 if (DEBUGLEVEL < 50) {
1326 return;
1329 len = smb_len_tcp(data)+4;
1330 for (i=1;i<100;i++) {
1331 fname = talloc_asprintf(talloc_tos(),
1332 "/tmp/%s.%d.%s",
1333 name,
1335 type ? "req" : "resp");
1336 if (fname == NULL) {
1337 return;
1339 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1340 if (fd != -1 || errno != EEXIST) break;
1341 TALLOC_FREE(fname);
1343 if (fd != -1) {
1344 ssize_t ret = write(fd, data, len);
1345 if (ret != len)
1346 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1347 close(fd);
1348 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1350 TALLOC_FREE(fname);
1353 /****************************************************************************
1354 Prepare everything for calling the actual request function, and potentially
1355 call the request function via the "new" interface.
1357 Return False if the "legacy" function needs to be called, everything is
1358 prepared.
1360 Return True if we're done.
1362 I know this API sucks, but it is the one with the least code change I could
1363 find.
1364 ****************************************************************************/
1366 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1368 int flags;
1369 uint64_t session_tag;
1370 connection_struct *conn = NULL;
1371 struct smbd_server_connection *sconn = req->sconn;
1372 NTTIME now = timeval_to_nttime(&req->request_time);
1373 struct smbXsrv_session *session = NULL;
1374 NTSTATUS status;
1376 errno = 0;
1378 if (smb_messages[type].fn == NULL) {
1379 DEBUG(0,("Unknown message type %d!\n",type));
1380 smb_dump("Unknown", 1, (const char *)req->inbuf);
1381 reply_unknown_new(req, type);
1382 return NULL;
1385 flags = smb_messages[type].flags;
1387 /* In share mode security we must ignore the vuid. */
1388 session_tag = req->vuid;
1389 conn = req->conn;
1391 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1392 (int)getpid(), (unsigned long)conn));
1394 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1396 /* Ensure this value is replaced in the incoming packet. */
1397 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1400 * Ensure the correct username is in current_user_info. This is a
1401 * really ugly bugfix for problems with multiple session_setup_and_X's
1402 * being done and allowing %U and %G substitutions to work correctly.
1403 * There is a reason this code is done here, don't move it unless you
1404 * know what you're doing... :-).
1405 * JRA.
1409 * lookup an existing session
1411 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1412 * here, the main check is still in change_to_user()
1414 status = smb1srv_session_lookup(sconn->conn,
1415 session_tag,
1416 now,
1417 &session);
1418 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1419 switch (type) {
1420 case SMBsesssetupX:
1421 status = NT_STATUS_OK;
1422 break;
1423 default:
1424 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1425 (unsigned long long)session_tag,
1426 (unsigned long long)req->mid));
1427 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1428 return conn;
1432 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1433 struct user_struct *vuser = NULL;
1435 sconn->smb1.sessions.last_session_tag = session_tag;
1436 if (session) {
1437 vuser = session->compat;
1439 if (vuser) {
1440 set_current_user_info(
1441 vuser->session_info->unix_info->sanitized_username,
1442 vuser->session_info->unix_info->unix_name,
1443 vuser->session_info->info->domain_name);
1447 /* Does this call need to be run as the connected user? */
1448 if (flags & AS_USER) {
1450 /* Does this call need a valid tree connection? */
1451 if (!conn) {
1453 * Amazingly, the error code depends on the command
1454 * (from Samba4).
1456 if (type == SMBntcreateX) {
1457 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1458 } else {
1459 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1461 return NULL;
1464 if (!change_to_user(conn,session_tag)) {
1465 DEBUG(0, ("Error: Could not change to user. Removing "
1466 "deferred open, mid=%llu.\n",
1467 (unsigned long long)req->mid));
1468 reply_force_doserror(req, ERRSRV, ERRbaduid);
1469 return conn;
1472 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1474 /* Does it need write permission? */
1475 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1476 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1477 return conn;
1480 /* IPC services are limited */
1481 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1482 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1483 return conn;
1485 } else {
1486 /* This call needs to be run as root */
1487 change_to_root_user();
1490 /* load service specific parameters */
1491 if (conn) {
1492 if (req->encrypted) {
1493 conn->encrypted_tid = true;
1494 /* encrypted required from now on. */
1495 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1496 } else if (ENCRYPTION_REQUIRED(conn)) {
1497 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1498 DEBUG(1,("service[%s] requires encryption"
1499 "%s ACCESS_DENIED. mid=%llu\n",
1500 lp_servicename(talloc_tos(), SNUM(conn)),
1501 smb_fn_name(type),
1502 (unsigned long long)req->mid));
1503 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1504 return conn;
1508 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1509 (flags & (AS_USER|DO_CHDIR)
1510 ?True:False))) {
1511 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1512 return conn;
1514 conn->num_smb_operations++;
1518 * Does this protocol need to be run as guest? (Only archane
1519 * messenger service requests have this...)
1521 if (flags & AS_GUEST) {
1522 char *raddr;
1523 bool ok;
1525 if (!change_to_guest()) {
1526 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1527 return conn;
1530 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1531 talloc_tos());
1532 if (raddr == NULL) {
1533 reply_nterror(req, NT_STATUS_NO_MEMORY);
1534 return conn;
1538 * Haven't we checked this in smbd_process already???
1541 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1542 sconn->remote_hostname, raddr);
1543 TALLOC_FREE(raddr);
1545 if (!ok) {
1546 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1547 return conn;
1551 smb_messages[type].fn(req);
1552 return req->conn;
1555 /****************************************************************************
1556 Construct a reply to the incoming packet.
1557 ****************************************************************************/
1559 static void construct_reply(struct smbd_server_connection *sconn,
1560 char *inbuf, int size, size_t unread_bytes,
1561 uint32_t seqnum, bool encrypted,
1562 struct smb_perfcount_data *deferred_pcd)
1564 connection_struct *conn;
1565 struct smb_request *req;
1567 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1568 smb_panic("could not allocate smb_request");
1571 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1572 encrypted, seqnum)) {
1573 exit_server_cleanly("Invalid SMB request");
1576 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1578 /* we popped this message off the queue - keep original perf data */
1579 if (deferred_pcd)
1580 req->pcd = *deferred_pcd;
1581 else {
1582 SMB_PERFCOUNT_START(&req->pcd);
1583 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1584 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1587 conn = switch_message(req->cmd, req);
1589 if (req->outbuf == NULL) {
1590 return;
1593 if (CVAL(req->outbuf,0) == 0) {
1594 show_msg((char *)req->outbuf);
1597 if (!srv_send_smb(req->sconn,
1598 (char *)req->outbuf,
1599 true, req->seqnum+1,
1600 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1601 &req->pcd)) {
1602 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1605 TALLOC_FREE(req);
1607 return;
1610 static void construct_reply_chain(struct smbd_server_connection *sconn,
1611 char *inbuf, int size, uint32_t seqnum,
1612 bool encrypted,
1613 struct smb_perfcount_data *deferred_pcd)
1615 struct smb_request **reqs = NULL;
1616 struct smb_request *req;
1617 unsigned num_reqs;
1618 bool ok;
1620 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1621 seqnum, &reqs, &num_reqs);
1622 if (!ok) {
1623 char errbuf[smb_size];
1624 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1625 __LINE__, __FILE__);
1626 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1627 NULL)) {
1628 exit_server_cleanly("construct_reply_chain: "
1629 "srv_send_smb failed.");
1631 return;
1634 req = reqs[0];
1635 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1637 req->conn = switch_message(req->cmd, req);
1639 if (req->outbuf == NULL) {
1641 * Request has suspended itself, will come
1642 * back here.
1644 return;
1646 smb_request_done(req);
1650 * To be called from an async SMB handler that is potentially chained
1651 * when it is finished for shipping.
1654 void smb_request_done(struct smb_request *req)
1656 struct smb_request **reqs = NULL;
1657 struct smb_request *first_req;
1658 size_t i, num_reqs, next_index;
1659 NTSTATUS status;
1661 if (req->chain == NULL) {
1662 first_req = req;
1663 goto shipit;
1666 reqs = req->chain;
1667 num_reqs = talloc_array_length(reqs);
1669 for (i=0; i<num_reqs; i++) {
1670 if (reqs[i] == req) {
1671 break;
1674 if (i == num_reqs) {
1676 * Invalid chain, should not happen
1678 status = NT_STATUS_INTERNAL_ERROR;
1679 goto error;
1681 next_index = i+1;
1683 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1684 struct smb_request *next = reqs[next_index];
1685 struct smbXsrv_tcon *tcon;
1686 NTTIME now = timeval_to_nttime(&req->request_time);
1688 next->vuid = SVAL(req->outbuf, smb_uid);
1689 next->tid = SVAL(req->outbuf, smb_tid);
1690 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1691 now, &tcon);
1692 if (NT_STATUS_IS_OK(status)) {
1693 req->conn = tcon->compat;
1694 } else {
1695 req->conn = NULL;
1697 next->chain_fsp = req->chain_fsp;
1698 next->inbuf = (uint8_t *)req->inbuf;
1700 req = next;
1701 req->conn = switch_message(req->cmd, req);
1703 if (req->outbuf == NULL) {
1705 * Request has suspended itself, will come
1706 * back here.
1708 return;
1710 next_index += 1;
1713 first_req = reqs[0];
1715 for (i=1; i<next_index; i++) {
1716 bool ok;
1718 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1719 if (!ok) {
1720 status = NT_STATUS_INTERNAL_ERROR;
1721 goto error;
1725 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1726 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1729 * This scary statement intends to set the
1730 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1731 * to the value last_req->outbuf carries
1733 SSVAL(first_req->outbuf, smb_flg2,
1734 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1735 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1738 * Transfer the error codes from the subrequest to the main one
1740 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1741 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1743 _smb_setlen_large(
1744 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1746 shipit:
1747 if (!srv_send_smb(first_req->sconn,
1748 (char *)first_req->outbuf,
1749 true, first_req->seqnum+1,
1750 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1751 &first_req->pcd)) {
1752 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1753 "failed.");
1755 TALLOC_FREE(req); /* non-chained case */
1756 TALLOC_FREE(reqs); /* chained case */
1757 return;
1759 error:
1761 char errbuf[smb_size];
1762 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1763 if (!srv_send_smb(req->sconn, errbuf, true,
1764 req->seqnum+1, req->encrypted,
1765 NULL)) {
1766 exit_server_cleanly("construct_reply_chain: "
1767 "srv_send_smb failed.");
1770 TALLOC_FREE(req); /* non-chained case */
1771 TALLOC_FREE(reqs); /* chained case */
1774 /****************************************************************************
1775 Process an smb from the client
1776 ****************************************************************************/
1777 static void process_smb(struct smbd_server_connection *sconn,
1778 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1779 uint32_t seqnum, bool encrypted,
1780 struct smb_perfcount_data *deferred_pcd)
1782 int msg_type = CVAL(inbuf,0);
1784 DO_PROFILE_INC(smb_count);
1786 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1787 smb_len(inbuf) ) );
1788 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1789 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1791 if (msg_type != NBSSmessage) {
1793 * NetBIOS session request, keepalive, etc.
1795 reply_special(sconn, (char *)inbuf, nread);
1796 goto done;
1799 if (sconn->using_smb2) {
1800 /* At this point we're not really using smb2,
1801 * we make the decision here.. */
1802 if (smbd_is_smb2_header(inbuf, nread)) {
1803 smbd_smb2_first_negprot(sconn, inbuf, nread);
1804 return;
1805 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1806 && CVAL(inbuf, smb_com) != 0x72) {
1807 /* This is a non-negprot SMB1 packet.
1808 Disable SMB2 from now on. */
1809 sconn->using_smb2 = false;
1813 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1814 * so subtract 4 from it. */
1815 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1816 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1817 smb_len(inbuf)));
1819 /* special magic for immediate exit */
1820 if ((nread == 9) &&
1821 (IVAL(inbuf, 4) == 0x74697865) &&
1822 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1823 uint8_t exitcode = CVAL(inbuf, 8);
1824 DEBUG(1, ("Exiting immediately with code %d\n",
1825 (int)exitcode));
1826 exit(exitcode);
1829 exit_server_cleanly("Non-SMB packet");
1832 show_msg((char *)inbuf);
1834 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1835 construct_reply_chain(sconn, (char *)inbuf, nread,
1836 seqnum, encrypted, deferred_pcd);
1837 } else {
1838 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1839 seqnum, encrypted, deferred_pcd);
1842 sconn->trans_num++;
1844 done:
1845 sconn->num_requests++;
1847 /* The timeout_processing function isn't run nearly
1848 often enough to implement 'max log size' without
1849 overrunning the size of the file by many megabytes.
1850 This is especially true if we are running at debug
1851 level 10. Checking every 50 SMBs is a nice
1852 tradeoff of performance vs log file size overrun. */
1854 if ((sconn->num_requests % 50) == 0 &&
1855 need_to_check_log_size()) {
1856 change_to_root_user();
1857 check_log_size();
1861 /****************************************************************************
1862 Return a string containing the function name of a SMB command.
1863 ****************************************************************************/
1865 const char *smb_fn_name(int type)
1867 const char *unknown_name = "SMBunknown";
1869 if (smb_messages[type].name == NULL)
1870 return(unknown_name);
1872 return(smb_messages[type].name);
1875 /****************************************************************************
1876 Helper functions for contruct_reply.
1877 ****************************************************************************/
1879 void add_to_common_flags2(uint32 v)
1881 common_flags2 |= v;
1884 void remove_from_common_flags2(uint32 v)
1886 common_flags2 &= ~v;
1889 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1890 char *outbuf)
1892 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1893 uint16_t out_flags2 = common_flags2;
1895 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1896 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1897 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1899 srv_set_message(outbuf,0,0,false);
1901 SCVAL(outbuf, smb_com, req->cmd);
1902 SIVAL(outbuf,smb_rcls,0);
1903 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1904 SSVAL(outbuf,smb_flg2, out_flags2);
1905 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1906 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1908 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1909 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1910 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1911 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1914 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1916 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1920 * @brief Find the smb_cmd offset of the last command pushed
1921 * @param[in] buf The buffer we're building up
1922 * @retval Where can we put our next andx cmd?
1924 * While chaining requests, the "next" request we're looking at needs to put
1925 * its SMB_Command before the data the previous request already built up added
1926 * to the chain. Find the offset to the place where we have to put our cmd.
1929 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1931 uint8_t cmd;
1932 size_t ofs;
1934 cmd = CVAL(buf, smb_com);
1936 if (!is_andx_req(cmd)) {
1937 return false;
1940 ofs = smb_vwv0;
1942 while (CVAL(buf, ofs) != 0xff) {
1944 if (!is_andx_req(CVAL(buf, ofs))) {
1945 return false;
1949 * ofs is from start of smb header, so add the 4 length
1950 * bytes. The next cmd is right after the wct field.
1952 ofs = SVAL(buf, ofs+2) + 4 + 1;
1954 if (ofs+4 >= talloc_get_size(buf)) {
1955 return false;
1959 *pofs = ofs;
1960 return true;
1964 * @brief Do the smb chaining at a buffer level
1965 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1966 * @param[in] andx_buf Buffer to be appended
1969 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1971 uint8_t smb_command = CVAL(andx_buf, smb_com);
1972 uint8_t wct = CVAL(andx_buf, smb_wct);
1973 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1974 uint32_t num_bytes = smb_buflen(andx_buf);
1975 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1977 uint8_t *outbuf;
1978 size_t old_size, new_size;
1979 size_t ofs;
1980 size_t chain_padding = 0;
1981 size_t andx_cmd_ofs;
1984 old_size = talloc_get_size(*poutbuf);
1986 if ((old_size % 4) != 0) {
1988 * Align the wct field of subsequent requests to a 4-byte
1989 * boundary
1991 chain_padding = 4 - (old_size % 4);
1995 * After the old request comes the new wct field (1 byte), the vwv's
1996 * and the num_bytes field.
1999 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2000 new_size += num_bytes;
2002 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2003 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2004 (unsigned)new_size));
2005 return false;
2008 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2009 if (outbuf == NULL) {
2010 DEBUG(0, ("talloc failed\n"));
2011 return false;
2013 *poutbuf = outbuf;
2015 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2016 DEBUG(1, ("invalid command chain\n"));
2017 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2018 return false;
2021 if (chain_padding != 0) {
2022 memset(outbuf + old_size, 0, chain_padding);
2023 old_size += chain_padding;
2026 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2027 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2029 ofs = old_size;
2032 * Push the chained request:
2034 * wct field
2037 SCVAL(outbuf, ofs, wct);
2038 ofs += 1;
2041 * vwv array
2044 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2047 * HACK ALERT
2049 * Read&X has an offset into its data buffer at
2050 * vwv[6]. reply_read_andx has no idea anymore that it's
2051 * running from within a chain, so we have to fix up the
2052 * offset here.
2054 * Although it looks disgusting at this place, I want to keep
2055 * it here. The alternative would be to push knowledge about
2056 * the andx chain down into read&x again.
2059 if (smb_command == SMBreadX) {
2060 uint8_t *bytes_addr;
2062 if (wct < 7) {
2064 * Invalid read&x response
2066 return false;
2069 bytes_addr = outbuf + ofs /* vwv start */
2070 + sizeof(uint16_t) * wct /* vwv array */
2071 + sizeof(uint16_t); /* bcc */
2073 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2074 bytes_addr - outbuf - 4);
2077 ofs += sizeof(uint16_t) * wct;
2080 * bcc (byte count)
2083 SSVAL(outbuf, ofs, num_bytes);
2084 ofs += sizeof(uint16_t);
2087 * The bytes field
2090 memcpy(outbuf + ofs, bytes, num_bytes);
2092 return true;
2095 bool smb1_is_chain(const uint8_t *buf)
2097 uint8_t cmd, wct, andx_cmd;
2099 cmd = CVAL(buf, smb_com);
2100 if (!is_andx_req(cmd)) {
2101 return false;
2103 wct = CVAL(buf, smb_wct);
2104 if (wct < 2) {
2105 return false;
2107 andx_cmd = CVAL(buf, smb_vwv);
2108 return (andx_cmd != 0xFF);
2111 bool smb1_walk_chain(const uint8_t *buf,
2112 bool (*fn)(uint8_t cmd,
2113 uint8_t wct, const uint16_t *vwv,
2114 uint16_t num_bytes, const uint8_t *bytes,
2115 void *private_data),
2116 void *private_data)
2118 size_t smblen = smb_len(buf);
2119 const char *smb_buf = smb_base(buf);
2120 uint8_t cmd, chain_cmd;
2121 uint8_t wct;
2122 const uint16_t *vwv;
2123 uint16_t num_bytes;
2124 const uint8_t *bytes;
2126 cmd = CVAL(buf, smb_com);
2127 wct = CVAL(buf, smb_wct);
2128 vwv = (const uint16_t *)(buf + smb_vwv);
2129 num_bytes = smb_buflen(buf);
2130 bytes = (uint8_t *)smb_buf_const(buf);
2132 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2133 return false;
2136 if (!is_andx_req(cmd)) {
2137 return true;
2139 if (wct < 2) {
2140 return false;
2143 chain_cmd = CVAL(vwv, 0);
2145 while (chain_cmd != 0xff) {
2146 uint32_t chain_offset; /* uint32_t to avoid overflow */
2147 size_t length_needed;
2148 ptrdiff_t vwv_offset;
2150 chain_offset = SVAL(vwv+1, 0);
2153 * Check if the client tries to fool us. The chain
2154 * offset needs to point beyond the current request in
2155 * the chain, it needs to strictly grow. Otherwise we
2156 * might be tricked into an endless loop always
2157 * processing the same request over and over again. We
2158 * used to assume that vwv and the byte buffer array
2159 * in a chain are always attached, but OS/2 the
2160 * Write&X/Read&X chain puts the Read&X vwv array
2161 * right behind the Write&X vwv chain. The Write&X bcc
2162 * array is put behind the Read&X vwv array. So now we
2163 * check whether the chain offset points strictly
2164 * behind the previous vwv array. req->buf points
2165 * right after the vwv array of the previous
2166 * request. See
2167 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2168 * more information.
2171 vwv_offset = ((const char *)vwv - smb_buf);
2172 if (chain_offset <= vwv_offset) {
2173 return false;
2177 * Next check: Make sure the chain offset does not
2178 * point beyond the overall smb request length.
2181 length_needed = chain_offset+1; /* wct */
2182 if (length_needed > smblen) {
2183 return false;
2187 * Now comes the pointer magic. Goal here is to set up
2188 * vwv and buf correctly again. The chain offset (the
2189 * former vwv[1]) points at the new wct field.
2192 wct = CVAL(smb_buf, chain_offset);
2194 if (is_andx_req(chain_cmd) && (wct < 2)) {
2195 return false;
2199 * Next consistency check: Make the new vwv array fits
2200 * in the overall smb request.
2203 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2204 if (length_needed > smblen) {
2205 return false;
2207 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2210 * Now grab the new byte buffer....
2213 num_bytes = SVAL(vwv+wct, 0);
2216 * .. and check that it fits.
2219 length_needed += num_bytes;
2220 if (length_needed > smblen) {
2221 return false;
2223 bytes = (const uint8_t *)(vwv+wct+1);
2225 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2226 return false;
2229 if (!is_andx_req(chain_cmd)) {
2230 return true;
2232 chain_cmd = CVAL(vwv, 0);
2234 return true;
2237 static bool smb1_chain_length_cb(uint8_t cmd,
2238 uint8_t wct, const uint16_t *vwv,
2239 uint16_t num_bytes, const uint8_t *bytes,
2240 void *private_data)
2242 unsigned *count = (unsigned *)private_data;
2243 *count += 1;
2244 return true;
2247 unsigned smb1_chain_length(const uint8_t *buf)
2249 unsigned count = 0;
2251 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2252 return 0;
2254 return count;
2257 struct smb1_parse_chain_state {
2258 TALLOC_CTX *mem_ctx;
2259 const uint8_t *buf;
2260 struct smbd_server_connection *sconn;
2261 bool encrypted;
2262 uint32_t seqnum;
2264 struct smb_request **reqs;
2265 unsigned num_reqs;
2268 static bool smb1_parse_chain_cb(uint8_t cmd,
2269 uint8_t wct, const uint16_t *vwv,
2270 uint16_t num_bytes, const uint8_t *bytes,
2271 void *private_data)
2273 struct smb1_parse_chain_state *state =
2274 (struct smb1_parse_chain_state *)private_data;
2275 struct smb_request **reqs;
2276 struct smb_request *req;
2277 bool ok;
2279 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2280 struct smb_request *, state->num_reqs+1);
2281 if (reqs == NULL) {
2282 return false;
2284 state->reqs = reqs;
2286 req = talloc(reqs, struct smb_request);
2287 if (req == NULL) {
2288 return false;
2291 ok = init_smb_request(req, state->sconn, state->buf, 0,
2292 state->encrypted, state->seqnum);
2293 if (!ok) {
2294 return false;
2296 req->cmd = cmd;
2297 req->wct = wct;
2298 req->vwv = vwv;
2299 req->buflen = num_bytes;
2300 req->buf = bytes;
2302 reqs[state->num_reqs] = req;
2303 state->num_reqs += 1;
2304 return true;
2307 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2308 struct smbd_server_connection *sconn,
2309 bool encrypted, uint32_t seqnum,
2310 struct smb_request ***reqs, unsigned *num_reqs)
2312 struct smb1_parse_chain_state state;
2313 unsigned i;
2315 state.mem_ctx = mem_ctx;
2316 state.buf = buf;
2317 state.sconn = sconn;
2318 state.encrypted = encrypted;
2319 state.seqnum = seqnum;
2320 state.reqs = NULL;
2321 state.num_reqs = 0;
2323 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2324 TALLOC_FREE(state.reqs);
2325 return false;
2327 for (i=0; i<state.num_reqs; i++) {
2328 state.reqs[i]->chain = state.reqs;
2330 *reqs = state.reqs;
2331 *num_reqs = state.num_reqs;
2332 return true;
2335 /****************************************************************************
2336 Check if services need reloading.
2337 ****************************************************************************/
2339 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2342 if (last_smb_conf_reload_time == 0) {
2343 last_smb_conf_reload_time = t;
2346 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2347 reload_services(sconn, conn_snum_used, true);
2348 last_smb_conf_reload_time = t;
2352 static bool fd_is_readable(int fd)
2354 int ret, revents;
2356 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2358 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2362 static void smbd_server_connection_write_handler(
2363 struct smbd_server_connection *sconn)
2365 /* TODO: make write nonblocking */
2368 static void smbd_server_connection_read_handler(
2369 struct smbd_server_connection *sconn, int fd)
2371 uint8_t *inbuf = NULL;
2372 size_t inbuf_len = 0;
2373 size_t unread_bytes = 0;
2374 bool encrypted = false;
2375 TALLOC_CTX *mem_ctx = talloc_tos();
2376 NTSTATUS status;
2377 uint32_t seqnum;
2379 bool from_client;
2381 if (lp_async_smb_echo_handler()
2382 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2384 * This is the super-ugly hack to prefer the packets
2385 * forwarded by the echo handler over the ones by the
2386 * client directly
2388 fd = sconn->smb1.echo_handler.trusted_fd;
2391 from_client = (sconn->sock == fd);
2393 if (from_client) {
2394 smbd_lock_socket(sconn);
2396 if (!fd_is_readable(fd)) {
2397 DEBUG(10,("the echo listener was faster\n"));
2398 smbd_unlock_socket(sconn);
2399 return;
2403 /* TODO: make this completely nonblocking */
2404 status = receive_smb_talloc(mem_ctx, sconn, fd,
2405 (char **)(void *)&inbuf,
2406 0, /* timeout */
2407 &unread_bytes,
2408 &encrypted,
2409 &inbuf_len, &seqnum,
2410 false /* trusted channel */);
2412 if (from_client) {
2413 smbd_unlock_socket(sconn);
2416 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2417 goto process;
2419 if (NT_STATUS_IS_ERR(status)) {
2420 exit_server_cleanly("failed to receive smb request");
2422 if (!NT_STATUS_IS_OK(status)) {
2423 return;
2426 process:
2427 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2428 seqnum, encrypted, NULL);
2431 static void smbd_server_connection_handler(struct event_context *ev,
2432 struct fd_event *fde,
2433 uint16_t flags,
2434 void *private_data)
2436 struct smbd_server_connection *conn = talloc_get_type(private_data,
2437 struct smbd_server_connection);
2439 if (flags & EVENT_FD_WRITE) {
2440 smbd_server_connection_write_handler(conn);
2441 return;
2443 if (flags & EVENT_FD_READ) {
2444 smbd_server_connection_read_handler(conn, conn->sock);
2445 return;
2449 static void smbd_server_echo_handler(struct event_context *ev,
2450 struct fd_event *fde,
2451 uint16_t flags,
2452 void *private_data)
2454 struct smbd_server_connection *conn = talloc_get_type(private_data,
2455 struct smbd_server_connection);
2457 if (flags & EVENT_FD_WRITE) {
2458 smbd_server_connection_write_handler(conn);
2459 return;
2461 if (flags & EVENT_FD_READ) {
2462 smbd_server_connection_read_handler(
2463 conn, conn->smb1.echo_handler.trusted_fd);
2464 return;
2468 #ifdef CLUSTER_SUPPORT
2470 struct smbd_release_ip_state {
2471 struct smbd_server_connection *sconn;
2472 char addr[INET6_ADDRSTRLEN];
2475 /****************************************************************************
2476 received when we should release a specific IP
2477 ****************************************************************************/
2478 static void release_ip(const char *ip, void *priv)
2480 struct smbd_release_ip_state *state =
2481 talloc_get_type_abort(priv,
2482 struct smbd_release_ip_state);
2483 const char *addr = state->addr;
2484 const char *p = addr;
2486 if (strncmp("::ffff:", addr, 7) == 0) {
2487 p = addr + 7;
2490 DEBUG(10, ("Got release IP message for %s, "
2491 "our address is %s\n", ip, p));
2493 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2494 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2495 ip));
2497 * With SMB2 we should do a clean disconnect,
2498 * the previous_session_id in the session setup
2499 * will cleanup the old session, tcons and opens.
2501 * A clean disconnect is needed in order to support
2502 * durable handles.
2504 * Note: typically this is never triggered
2505 * as we got a TCP RST (triggered by ctdb event scripts)
2506 * before we get CTDB_SRVID_RELEASE_IP.
2508 * We used to call _exit(1) here, but as this was mostly never
2509 * triggered and has implication on our process model,
2510 * we can just use smbd_server_connection_terminate()
2511 * (also for SMB1).
2513 smbd_server_connection_terminate(state->sconn,
2514 "CTDB_SRVID_RELEASE_IP");
2515 return;
2519 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2520 struct sockaddr_storage *srv,
2521 struct sockaddr_storage *clnt)
2523 struct smbd_release_ip_state *state;
2524 struct ctdbd_connection *cconn;
2526 cconn = messaging_ctdbd_connection();
2527 if (cconn == NULL) {
2528 return NT_STATUS_NO_MEMORY;
2531 state = talloc_zero(sconn, struct smbd_release_ip_state);
2532 if (state == NULL) {
2533 return NT_STATUS_NO_MEMORY;
2535 state->sconn = sconn;
2536 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2537 return NT_STATUS_NO_MEMORY;
2540 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2543 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2544 struct sockaddr_storage *client)
2546 socklen_t length;
2547 length = sizeof(*server);
2548 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2549 return -1;
2551 length = sizeof(*client);
2552 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2553 return -1;
2555 return 0;
2557 #endif
2560 * Send keepalive packets to our client
2562 static bool keepalive_fn(const struct timeval *now, void *private_data)
2564 struct smbd_server_connection *sconn = talloc_get_type_abort(
2565 private_data, struct smbd_server_connection);
2566 bool ret;
2568 if (sconn->using_smb2) {
2569 /* Don't do keepalives on an SMB2 connection. */
2570 return false;
2573 smbd_lock_socket(sconn);
2574 ret = send_keepalive(sconn->sock);
2575 smbd_unlock_socket(sconn);
2577 if (!ret) {
2578 char addr[INET6_ADDRSTRLEN];
2580 * Try and give an error message saying what
2581 * client failed.
2583 DEBUG(0, ("send_keepalive failed for client %s. "
2584 "Error %s - exiting\n",
2585 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2586 strerror(errno)));
2587 return False;
2589 return True;
2593 * Do the recurring check if we're idle
2595 static bool deadtime_fn(const struct timeval *now, void *private_data)
2597 struct smbd_server_connection *sconn =
2598 (struct smbd_server_connection *)private_data;
2600 if ((conn_num_open(sconn) == 0)
2601 || (conn_idle_all(sconn, now->tv_sec))) {
2602 DEBUG( 2, ( "Closing idle connection\n" ) );
2603 messaging_send(sconn->msg_ctx,
2604 messaging_server_id(sconn->msg_ctx),
2605 MSG_SHUTDOWN, &data_blob_null);
2606 return False;
2609 return True;
2613 * Do the recurring log file and smb.conf reload checks.
2616 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2618 struct smbd_server_connection *sconn = talloc_get_type_abort(
2619 private_data, struct smbd_server_connection);
2621 DEBUG(5, ("housekeeping\n"));
2623 change_to_root_user();
2625 /* update printer queue caches if necessary */
2626 update_monitored_printq_cache(sconn->msg_ctx);
2628 /* check if we need to reload services */
2629 check_reload(sconn, time_mono(NULL));
2632 * Force a log file check.
2634 force_check_log_size();
2635 check_log_size();
2636 return true;
2640 * Read an smb packet in the echo handler child, giving the parent
2641 * smbd one second to react once the socket becomes readable.
2644 struct smbd_echo_read_state {
2645 struct tevent_context *ev;
2646 struct smbd_server_connection *sconn;
2648 char *buf;
2649 size_t buflen;
2650 uint32_t seqnum;
2653 static void smbd_echo_read_readable(struct tevent_req *subreq);
2654 static void smbd_echo_read_waited(struct tevent_req *subreq);
2656 static struct tevent_req *smbd_echo_read_send(
2657 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2658 struct smbd_server_connection *sconn)
2660 struct tevent_req *req, *subreq;
2661 struct smbd_echo_read_state *state;
2663 req = tevent_req_create(mem_ctx, &state,
2664 struct smbd_echo_read_state);
2665 if (req == NULL) {
2666 return NULL;
2668 state->ev = ev;
2669 state->sconn = sconn;
2671 subreq = wait_for_read_send(state, ev, sconn->sock);
2672 if (tevent_req_nomem(subreq, req)) {
2673 return tevent_req_post(req, ev);
2675 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2676 return req;
2679 static void smbd_echo_read_readable(struct tevent_req *subreq)
2681 struct tevent_req *req = tevent_req_callback_data(
2682 subreq, struct tevent_req);
2683 struct smbd_echo_read_state *state = tevent_req_data(
2684 req, struct smbd_echo_read_state);
2685 bool ok;
2686 int err;
2688 ok = wait_for_read_recv(subreq, &err);
2689 TALLOC_FREE(subreq);
2690 if (!ok) {
2691 tevent_req_nterror(req, map_nt_error_from_unix(err));
2692 return;
2696 * Give the parent smbd one second to step in
2699 subreq = tevent_wakeup_send(
2700 state, state->ev, timeval_current_ofs(1, 0));
2701 if (tevent_req_nomem(subreq, req)) {
2702 return;
2704 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2707 static void smbd_echo_read_waited(struct tevent_req *subreq)
2709 struct tevent_req *req = tevent_req_callback_data(
2710 subreq, struct tevent_req);
2711 struct smbd_echo_read_state *state = tevent_req_data(
2712 req, struct smbd_echo_read_state);
2713 struct smbd_server_connection *sconn = state->sconn;
2714 bool ok;
2715 NTSTATUS status;
2716 size_t unread = 0;
2717 bool encrypted;
2719 ok = tevent_wakeup_recv(subreq);
2720 TALLOC_FREE(subreq);
2721 if (!ok) {
2722 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2723 return;
2726 ok = smbd_lock_socket_internal(sconn);
2727 if (!ok) {
2728 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2729 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2730 return;
2733 if (!fd_is_readable(sconn->sock)) {
2734 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2735 (int)getpid()));
2737 ok = smbd_unlock_socket_internal(sconn);
2738 if (!ok) {
2739 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2740 DEBUG(1, ("%s: failed to unlock socket\n",
2741 __location__));
2742 return;
2745 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2746 if (tevent_req_nomem(subreq, req)) {
2747 return;
2749 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2750 return;
2753 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2754 0 /* timeout */,
2755 &unread,
2756 &encrypted,
2757 &state->buflen,
2758 &state->seqnum,
2759 false /* trusted_channel*/);
2761 if (tevent_req_nterror(req, status)) {
2762 tevent_req_nterror(req, status);
2763 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2764 (int)getpid(), nt_errstr(status)));
2765 return;
2768 ok = smbd_unlock_socket_internal(sconn);
2769 if (!ok) {
2770 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2771 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2772 return;
2774 tevent_req_done(req);
2777 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2778 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2780 struct smbd_echo_read_state *state = tevent_req_data(
2781 req, struct smbd_echo_read_state);
2782 NTSTATUS status;
2784 if (tevent_req_is_nterror(req, &status)) {
2785 return status;
2787 *pbuf = talloc_move(mem_ctx, &state->buf);
2788 *pbuflen = state->buflen;
2789 *pseqnum = state->seqnum;
2790 return NT_STATUS_OK;
2793 struct smbd_echo_state {
2794 struct tevent_context *ev;
2795 struct iovec *pending;
2796 struct smbd_server_connection *sconn;
2797 int parent_pipe;
2799 struct tevent_fd *parent_fde;
2801 struct tevent_req *write_req;
2804 static void smbd_echo_writer_done(struct tevent_req *req);
2806 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2808 int num_pending;
2810 if (state->write_req != NULL) {
2811 return;
2814 num_pending = talloc_array_length(state->pending);
2815 if (num_pending == 0) {
2816 return;
2819 state->write_req = writev_send(state, state->ev, NULL,
2820 state->parent_pipe, false,
2821 state->pending, num_pending);
2822 if (state->write_req == NULL) {
2823 DEBUG(1, ("writev_send failed\n"));
2824 exit(1);
2827 talloc_steal(state->write_req, state->pending);
2828 state->pending = NULL;
2830 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2831 state);
2834 static void smbd_echo_writer_done(struct tevent_req *req)
2836 struct smbd_echo_state *state = tevent_req_callback_data(
2837 req, struct smbd_echo_state);
2838 ssize_t written;
2839 int err;
2841 written = writev_recv(req, &err);
2842 TALLOC_FREE(req);
2843 state->write_req = NULL;
2844 if (written == -1) {
2845 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2846 exit(1);
2848 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2849 smbd_echo_activate_writer(state);
2852 static bool smbd_echo_reply(struct smbd_echo_state *state,
2853 uint8_t *inbuf, size_t inbuf_len,
2854 uint32_t seqnum)
2856 struct smb_request req;
2857 uint16_t num_replies;
2858 char *outbuf;
2859 bool ok;
2861 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2862 DEBUG(10, ("Got netbios keepalive\n"));
2864 * Just swallow it
2866 return true;
2869 if (inbuf_len < smb_size) {
2870 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2871 return false;
2873 if (!valid_smb_header(state->sconn, inbuf)) {
2874 DEBUG(10, ("Got invalid SMB header\n"));
2875 return false;
2878 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2879 seqnum)) {
2880 return false;
2882 req.inbuf = inbuf;
2884 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2885 smb_messages[req.cmd].name
2886 ? smb_messages[req.cmd].name : "unknown"));
2888 if (req.cmd != SMBecho) {
2889 return false;
2891 if (req.wct < 1) {
2892 return false;
2895 num_replies = SVAL(req.vwv+0, 0);
2896 if (num_replies != 1) {
2897 /* Not a Windows "Hey, you're still there?" request */
2898 return false;
2901 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2902 1, req.buflen)) {
2903 DEBUG(10, ("create_outbuf failed\n"));
2904 return false;
2906 req.outbuf = (uint8_t *)outbuf;
2908 SSVAL(req.outbuf, smb_vwv0, num_replies);
2910 if (req.buflen > 0) {
2911 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2914 ok = srv_send_smb(req.sconn,
2915 (char *)outbuf,
2916 true, seqnum+1,
2917 false, &req.pcd);
2918 TALLOC_FREE(outbuf);
2919 if (!ok) {
2920 exit(1);
2923 return true;
2926 static void smbd_echo_exit(struct tevent_context *ev,
2927 struct tevent_fd *fde, uint16_t flags,
2928 void *private_data)
2930 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2931 exit(0);
2934 static void smbd_echo_got_packet(struct tevent_req *req);
2936 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2937 int parent_pipe)
2939 struct smbd_echo_state *state;
2940 struct tevent_req *read_req;
2942 state = talloc_zero(sconn, struct smbd_echo_state);
2943 if (state == NULL) {
2944 DEBUG(1, ("talloc failed\n"));
2945 return;
2947 state->sconn = sconn;
2948 state->parent_pipe = parent_pipe;
2949 state->ev = s3_tevent_context_init(state);
2950 if (state->ev == NULL) {
2951 DEBUG(1, ("tevent_context_init failed\n"));
2952 TALLOC_FREE(state);
2953 return;
2955 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2956 TEVENT_FD_READ, smbd_echo_exit,
2957 state);
2958 if (state->parent_fde == NULL) {
2959 DEBUG(1, ("tevent_add_fd failed\n"));
2960 TALLOC_FREE(state);
2961 return;
2964 read_req = smbd_echo_read_send(state, state->ev, sconn);
2965 if (read_req == NULL) {
2966 DEBUG(1, ("smbd_echo_read_send failed\n"));
2967 TALLOC_FREE(state);
2968 return;
2970 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2972 while (true) {
2973 if (tevent_loop_once(state->ev) == -1) {
2974 DEBUG(1, ("tevent_loop_once failed: %s\n",
2975 strerror(errno)));
2976 break;
2979 TALLOC_FREE(state);
2982 static void smbd_echo_got_packet(struct tevent_req *req)
2984 struct smbd_echo_state *state = tevent_req_callback_data(
2985 req, struct smbd_echo_state);
2986 NTSTATUS status;
2987 char *buf = NULL;
2988 size_t buflen = 0;
2989 uint32_t seqnum = 0;
2990 bool reply;
2992 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2993 TALLOC_FREE(req);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2996 nt_errstr(status)));
2997 exit(1);
3000 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3001 if (!reply) {
3002 size_t num_pending;
3003 struct iovec *tmp;
3004 struct iovec *iov;
3006 num_pending = talloc_array_length(state->pending);
3007 tmp = talloc_realloc(state, state->pending, struct iovec,
3008 num_pending+1);
3009 if (tmp == NULL) {
3010 DEBUG(1, ("talloc_realloc failed\n"));
3011 exit(1);
3013 state->pending = tmp;
3015 if (buflen >= smb_size) {
3017 * place the seqnum in the packet so that the main process
3018 * can reply with signing
3020 SIVAL(buf, smb_ss_field, seqnum);
3021 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3024 iov = &state->pending[num_pending];
3025 iov->iov_base = buf;
3026 iov->iov_len = buflen;
3028 DEBUG(10,("echo_handler[%d]: forward to main\n",
3029 (int)getpid()));
3030 smbd_echo_activate_writer(state);
3033 req = smbd_echo_read_send(state, state->ev, state->sconn);
3034 if (req == NULL) {
3035 DEBUG(1, ("smbd_echo_read_send failed\n"));
3036 exit(1);
3038 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3043 * Handle SMBecho requests in a forked child process
3045 bool fork_echo_handler(struct smbd_server_connection *sconn)
3047 int listener_pipe[2];
3048 int res;
3049 pid_t child;
3051 res = pipe(listener_pipe);
3052 if (res == -1) {
3053 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3054 return false;
3056 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3057 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3058 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3059 goto fail;
3062 child = fork();
3063 if (child == 0) {
3064 NTSTATUS status;
3066 close(listener_pipe[0]);
3067 set_blocking(listener_pipe[1], false);
3069 status = reinit_after_fork(sconn->msg_ctx,
3070 sconn->ev_ctx,
3071 false);
3072 if (!NT_STATUS_IS_OK(status)) {
3073 DEBUG(1, ("reinit_after_fork failed: %s\n",
3074 nt_errstr(status)));
3075 exit(1);
3077 smbd_echo_loop(sconn, listener_pipe[1]);
3078 exit(0);
3080 close(listener_pipe[1]);
3081 listener_pipe[1] = -1;
3082 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3084 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
3087 * Without smb signing this is the same as the normal smbd
3088 * listener. This needs to change once signing comes in.
3090 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3091 sconn,
3092 sconn->smb1.echo_handler.trusted_fd,
3093 TEVENT_FD_READ,
3094 smbd_server_echo_handler,
3095 sconn);
3096 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3097 DEBUG(1, ("event_add_fd failed\n"));
3098 goto fail;
3101 return true;
3103 fail:
3104 if (listener_pipe[0] != -1) {
3105 close(listener_pipe[0]);
3107 if (listener_pipe[1] != -1) {
3108 close(listener_pipe[1]);
3110 sconn->smb1.echo_handler.trusted_fd = -1;
3111 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3112 close(sconn->smb1.echo_handler.socket_lock_fd);
3114 sconn->smb1.echo_handler.trusted_fd = -1;
3115 sconn->smb1.echo_handler.socket_lock_fd = -1;
3116 return false;
3119 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3121 while (user) {
3122 if (user->session_info &&
3123 (user->session_info->unix_token->uid == uid)) {
3124 return true;
3126 user = user->next;
3128 return false;
3131 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3133 while (user) {
3134 if (user->session_info != NULL) {
3135 int i;
3136 struct security_unix_token *utok;
3138 utok = user->session_info->unix_token;
3139 if (utok->gid == gid) {
3140 return true;
3142 for(i=0; i<utok->ngroups; i++) {
3143 if (utok->groups[i] == gid) {
3144 return true;
3148 user = user->next;
3150 return false;
3153 static bool sid_in_use(const struct user_struct *user,
3154 const struct dom_sid *psid)
3156 while (user) {
3157 struct security_token *tok;
3159 if (user->session_info == NULL) {
3160 continue;
3162 tok = user->session_info->security_token;
3163 if (tok == NULL) {
3165 * Not sure session_info->security_token can
3166 * ever be NULL. This check might be not
3167 * necessary.
3169 continue;
3171 if (security_token_has_sid(tok, psid)) {
3172 return true;
3174 user = user->next;
3176 return false;
3179 static bool id_in_use(const struct user_struct *user,
3180 const struct id_cache_ref *id)
3182 switch(id->type) {
3183 case UID:
3184 return uid_in_use(user, id->id.uid);
3185 case GID:
3186 return gid_in_use(user, id->id.gid);
3187 case SID:
3188 return sid_in_use(user, &id->id.sid);
3189 default:
3190 break;
3192 return false;
3195 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3196 void *private_data,
3197 uint32_t msg_type,
3198 struct server_id server_id,
3199 DATA_BLOB* data)
3201 const char *msg = (data && data->data)
3202 ? (const char *)data->data : "<NULL>";
3203 struct id_cache_ref id;
3204 struct smbd_server_connection *sconn =
3205 talloc_get_type_abort(private_data,
3206 struct smbd_server_connection);
3208 if (!id_cache_ref_parse(msg, &id)) {
3209 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3210 return;
3213 if (id_in_use(sconn->users, &id)) {
3214 exit_server_cleanly(msg);
3216 id_cache_delete_from_cache(&id);
3219 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3220 enum protocol_types protocol)
3222 NTSTATUS status;
3224 set_Protocol(protocol);
3225 conn->protocol = protocol;
3227 if (protocol >= PROTOCOL_SMB2_02) {
3228 status = smb2srv_session_table_init(conn);
3229 if (!NT_STATUS_IS_OK(status)) {
3230 return status;
3233 status = smb2srv_open_table_init(conn);
3234 if (!NT_STATUS_IS_OK(status)) {
3235 return status;
3237 } else {
3238 status = smb1srv_session_table_init(conn);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 return status;
3243 status = smb1srv_tcon_table_init(conn);
3244 if (!NT_STATUS_IS_OK(status)) {
3245 return status;
3248 status = smb1srv_open_table_init(conn);
3249 if (!NT_STATUS_IS_OK(status)) {
3250 return status;
3254 return NT_STATUS_OK;
3257 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3258 void *private_data)
3260 struct smbXsrv_connection *conn =
3261 talloc_get_type_abort(private_data,
3262 struct smbXsrv_connection);
3264 switch (point) {
3265 case TEVENT_TRACE_BEFORE_WAIT:
3267 * This just removes compiler warning
3268 * without profile support
3270 conn->smbd_idle_profstamp = 0;
3271 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3272 break;
3273 case TEVENT_TRACE_AFTER_WAIT:
3274 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3275 break;
3279 /****************************************************************************
3280 Process commands from the client
3281 ****************************************************************************/
3283 void smbd_process(struct tevent_context *ev_ctx,
3284 struct messaging_context *msg_ctx,
3285 int sock_fd,
3286 bool interactive)
3288 TALLOC_CTX *frame = talloc_stackframe();
3289 struct smbXsrv_connection *conn;
3290 struct smbd_server_connection *sconn;
3291 struct sockaddr_storage ss;
3292 struct sockaddr *sa = NULL;
3293 socklen_t sa_socklen;
3294 struct tsocket_address *local_address = NULL;
3295 struct tsocket_address *remote_address = NULL;
3296 const char *locaddr = NULL;
3297 const char *remaddr = NULL;
3298 char *rhost;
3299 int ret;
3301 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3302 if (conn == NULL) {
3303 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3304 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3307 conn->ev_ctx = ev_ctx;
3308 conn->msg_ctx = msg_ctx;
3310 sconn = talloc_zero(conn, struct smbd_server_connection);
3311 if (!sconn) {
3312 exit_server("failed to create smbd_server_connection");
3315 conn->sconn = sconn;
3316 sconn->conn = conn;
3319 * TODO: remove this...:-)
3321 global_smbXsrv_connection = conn;
3323 sconn->ev_ctx = ev_ctx;
3324 sconn->msg_ctx = msg_ctx;
3325 sconn->sock = sock_fd;
3326 sconn->smb1.echo_handler.trusted_fd = -1;
3327 sconn->smb1.echo_handler.socket_lock_fd = -1;
3329 if (!interactive) {
3330 smbd_setup_sig_term_handler(sconn);
3331 smbd_setup_sig_hup_handler(sconn);
3333 if (!serverid_register(messaging_server_id(msg_ctx),
3334 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3335 |FLAG_MSG_DBWRAP
3336 |FLAG_MSG_PRINT_GENERAL)) {
3337 exit_server_cleanly("Could not register myself in "
3338 "serverid.tdb");
3342 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3344 * We're not making the decision here,
3345 * we're just allowing the client
3346 * to decide between SMB1 and SMB2
3347 * with the first negprot
3348 * packet.
3350 sconn->using_smb2 = true;
3353 /* Ensure child is set to blocking mode */
3354 set_blocking(sconn->sock,True);
3356 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3357 set_socket_options(sconn->sock, lp_socket_options());
3359 sa = (struct sockaddr *)(void *)&ss;
3360 sa_socklen = sizeof(ss);
3361 ret = getpeername(sconn->sock, sa, &sa_socklen);
3362 if (ret != 0) {
3363 int level = (errno == ENOTCONN)?2:0;
3364 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3365 exit_server_cleanly("getpeername() failed.\n");
3367 ret = tsocket_address_bsd_from_sockaddr(sconn,
3368 sa, sa_socklen,
3369 &remote_address);
3370 if (ret != 0) {
3371 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3372 __location__, strerror(errno)));
3373 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3376 sa = (struct sockaddr *)(void *)&ss;
3377 sa_socklen = sizeof(ss);
3378 ret = getsockname(sconn->sock, sa, &sa_socklen);
3379 if (ret != 0) {
3380 int level = (errno == ENOTCONN)?2:0;
3381 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3382 exit_server_cleanly("getsockname() failed.\n");
3384 ret = tsocket_address_bsd_from_sockaddr(sconn,
3385 sa, sa_socklen,
3386 &local_address);
3387 if (ret != 0) {
3388 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3389 __location__, strerror(errno)));
3390 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3393 sconn->local_address = local_address;
3394 sconn->remote_address = remote_address;
3396 if (tsocket_address_is_inet(local_address, "ip")) {
3397 locaddr = tsocket_address_inet_addr_string(
3398 sconn->local_address,
3399 talloc_tos());
3400 if (locaddr == NULL) {
3401 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3402 __location__, strerror(errno)));
3403 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3405 } else {
3406 locaddr = "0.0.0.0";
3409 if (tsocket_address_is_inet(remote_address, "ip")) {
3410 remaddr = tsocket_address_inet_addr_string(
3411 sconn->remote_address,
3412 talloc_tos());
3413 if (remaddr == NULL) {
3414 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3415 __location__, strerror(errno)));
3416 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3418 } else {
3419 remaddr = "0.0.0.0";
3422 /* this is needed so that we get decent entries
3423 in smbstatus for port 445 connects */
3424 set_remote_machine_name(remaddr, false);
3425 reload_services(sconn, conn_snum_used, true);
3428 * Before the first packet, check the global hosts allow/ hosts deny
3429 * parameters before doing any parsing of packets passed to us by the
3430 * client. This prevents attacks on our parsing code from hosts not in
3431 * the hosts allow list.
3434 ret = get_remote_hostname(remote_address,
3435 &rhost,
3436 talloc_tos());
3437 if (ret < 0) {
3438 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3439 __location__, strerror(errno)));
3440 exit_server_cleanly("get_remote_hostname failed.\n");
3442 if (strequal(rhost, "UNKNOWN")) {
3443 rhost = talloc_strdup(talloc_tos(), remaddr);
3445 sconn->remote_hostname = talloc_move(sconn, &rhost);
3447 sub_set_socket_ids(remaddr,
3448 sconn->remote_hostname,
3449 locaddr);
3451 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3452 sconn->remote_hostname,
3453 remaddr)) {
3455 * send a negative session response "not listening on calling
3456 * name"
3458 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3459 DEBUG( 1, ("Connection denied from %s to %s\n",
3460 tsocket_address_string(remote_address, talloc_tos()),
3461 tsocket_address_string(local_address, talloc_tos())));
3462 (void)srv_send_smb(sconn,(char *)buf, false,
3463 0, false, NULL);
3464 exit_server_cleanly("connection denied");
3467 DEBUG(10, ("Connection allowed from %s to %s\n",
3468 tsocket_address_string(remote_address, talloc_tos()),
3469 tsocket_address_string(local_address, talloc_tos())));
3471 if (lp_preload_modules()) {
3472 smb_load_modules(lp_preload_modules());
3475 smb_perfcount_init();
3477 if (!init_account_policy()) {
3478 exit_server("Could not open account policy tdb.\n");
3481 if (*lp_rootdir(talloc_tos())) {
3482 if (chroot(lp_rootdir(talloc_tos())) != 0) {
3483 DEBUG(0,("Failed to change root to %s\n",
3484 lp_rootdir(talloc_tos())));
3485 exit_server("Failed to chroot()");
3487 if (chdir("/") == -1) {
3488 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
3489 exit_server("Failed to chroot()");
3491 DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
3494 if (!srv_init_signing(sconn)) {
3495 exit_server("Failed to init smb_signing");
3498 if (!file_init(sconn)) {
3499 exit_server("file_init() failed");
3502 /* Setup oplocks */
3503 if (!init_oplocks(sconn))
3504 exit_server("Failed to init oplocks");
3506 /* register our message handlers */
3507 messaging_register(sconn->msg_ctx, sconn,
3508 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3509 messaging_register(sconn->msg_ctx, sconn,
3510 MSG_SMB_CLOSE_FILE, msg_close_file);
3511 messaging_register(sconn->msg_ctx, sconn,
3512 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3514 id_cache_register_msgs(sconn->msg_ctx);
3515 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3516 messaging_register(sconn->msg_ctx, sconn,
3517 ID_CACHE_KILL, smbd_id_cache_kill);
3519 messaging_deregister(sconn->msg_ctx,
3520 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3521 messaging_register(sconn->msg_ctx, sconn,
3522 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3525 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3526 * MSGs to all child processes
3528 messaging_deregister(sconn->msg_ctx,
3529 MSG_DEBUG, NULL);
3530 messaging_register(sconn->msg_ctx, NULL,
3531 MSG_DEBUG, debug_message);
3533 if ((lp_keepalive() != 0)
3534 && !(event_add_idle(ev_ctx, NULL,
3535 timeval_set(lp_keepalive(), 0),
3536 "keepalive", keepalive_fn,
3537 sconn))) {
3538 DEBUG(0, ("Could not add keepalive event\n"));
3539 exit(1);
3542 if (!(event_add_idle(ev_ctx, NULL,
3543 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3544 "deadtime", deadtime_fn, sconn))) {
3545 DEBUG(0, ("Could not add deadtime event\n"));
3546 exit(1);
3549 if (!(event_add_idle(ev_ctx, NULL,
3550 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3551 "housekeeping", housekeeping_fn, sconn))) {
3552 DEBUG(0, ("Could not add housekeeping event\n"));
3553 exit(1);
3556 #ifdef CLUSTER_SUPPORT
3558 if (lp_clustering()) {
3560 * We need to tell ctdb about our client's TCP
3561 * connection, so that for failover ctdbd can send
3562 * tickle acks, triggering a reconnection by the
3563 * client.
3566 struct sockaddr_storage srv, clnt;
3568 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3569 NTSTATUS status;
3570 status = smbd_register_ips(sconn, &srv, &clnt);
3571 if (!NT_STATUS_IS_OK(status)) {
3572 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3573 nt_errstr(status)));
3575 } else
3577 DEBUG(0,("Unable to get tcp info for "
3578 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3579 strerror(errno)));
3583 #endif
3585 sconn->nbt.got_session = false;
3587 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3589 sconn->smb1.sessions.done_sesssetup = false;
3590 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3591 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3593 if (!init_dptrs(sconn)) {
3594 exit_server("init_dptrs() failed");
3597 sconn->smb1.fde = event_add_fd(ev_ctx,
3598 sconn,
3599 sconn->sock,
3600 EVENT_FD_READ,
3601 smbd_server_connection_handler,
3602 sconn);
3603 if (!sconn->smb1.fde) {
3604 exit_server("failed to create smbd_server_connection fde");
3607 sconn->conn->local_address = sconn->local_address;
3608 sconn->conn->remote_address = sconn->remote_address;
3609 sconn->conn->remote_hostname = sconn->remote_hostname;
3610 sconn->conn->protocol = PROTOCOL_NONE;
3612 TALLOC_FREE(frame);
3614 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3616 while (True) {
3617 frame = talloc_stackframe_pool(8192);
3619 errno = 0;
3620 if (tevent_loop_once(ev_ctx) == -1) {
3621 if (errno != EINTR) {
3622 DEBUG(3, ("tevent_loop_once failed: %s,"
3623 " exiting\n", strerror(errno) ));
3624 break;
3628 TALLOC_FREE(frame);
3631 exit_server_cleanly(NULL);
3634 bool req_is_in_chain(struct smb_request *req)
3636 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3638 * We're right now handling a subsequent request, so we must
3639 * be in a chain
3641 return true;
3644 if (!is_andx_req(req->cmd)) {
3645 return false;
3648 if (req->wct < 2) {
3650 * Okay, an illegal request, but definitely not chained :-)
3652 return false;
3655 return (CVAL(req->vwv+0, 0) != 0xFF);