s3:smbd/sesssetup: implement dynamic re-authentication and expire session if client...
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
bloba437a9813b464d12b5a7b8de266d364d54ebca42
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 extern bool global_machine_password_needs_changing;
46 /* Internal message queue for deferred opens. */
47 struct pending_message_list {
48 struct pending_message_list *next, *prev;
49 struct timeval request_time; /* When was this first issued? */
50 struct smbd_server_connection *sconn;
51 struct timed_event *te;
52 struct smb_perfcount_data pcd;
53 uint32_t seqnum;
54 bool encrypted;
55 bool processed;
56 DATA_BLOB buf;
57 DATA_BLOB private_data;
60 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 char *outbuf);
62 static struct pending_message_list *get_deferred_open_message_smb(
63 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
68 bool ok;
70 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
71 return true;
74 sconn->smb1.echo_handler.ref_count++;
76 if (sconn->smb1.echo_handler.ref_count > 1) {
77 return true;
80 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
82 do {
83 ok = fcntl_lock(
84 sconn->smb1.echo_handler.socket_lock_fd,
85 F_SETLKW, 0, 0, F_WRLCK);
86 } while (!ok && (errno == EINTR));
88 if (!ok) {
89 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
90 return false;
93 DEBUG(10,("pid[%d] got for socket lock\n", (int)getpid()));
95 return true;
98 void smbd_lock_socket(struct smbd_server_connection *sconn)
100 if (!smbd_lock_socket_internal(sconn)) {
101 exit_server_cleanly("failed to lock socket");
105 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
107 bool ok;
109 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
110 return true;
113 sconn->smb1.echo_handler.ref_count--;
115 if (sconn->smb1.echo_handler.ref_count > 0) {
116 return true;
119 do {
120 ok = fcntl_lock(
121 sconn->smb1.echo_handler.socket_lock_fd,
122 F_SETLKW, 0, 0, F_UNLCK);
123 } while (!ok && (errno == EINTR));
125 if (!ok) {
126 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
127 return false;
130 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
132 return true;
135 void smbd_unlock_socket(struct smbd_server_connection *sconn)
137 if (!smbd_unlock_socket_internal(sconn)) {
138 exit_server_cleanly("failed to unlock socket");
142 /* Accessor function for smb_read_error for smbd functions. */
144 /****************************************************************************
145 Send an smb to a fd.
146 ****************************************************************************/
148 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
149 bool do_signing, uint32_t seqnum,
150 bool do_encrypt,
151 struct smb_perfcount_data *pcd)
153 size_t len = 0;
154 size_t nwritten=0;
155 ssize_t ret;
156 char *buf_out = buffer;
158 smbd_lock_socket(sconn);
160 if (do_signing) {
161 /* Sign the outgoing packet if required. */
162 srv_calculate_sign_mac(sconn, buf_out, seqnum);
165 if (do_encrypt) {
166 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
167 if (!NT_STATUS_IS_OK(status)) {
168 DEBUG(0, ("send_smb: SMB encryption failed "
169 "on outgoing packet! Error %s\n",
170 nt_errstr(status) ));
171 goto out;
175 len = smb_len(buf_out) + 4;
177 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
178 if (ret <= 0) {
180 char addr[INET6_ADDRSTRLEN];
182 * Try and give an error message saying what
183 * client failed.
185 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
186 (int)getpid(), (int)len,
187 get_peer_addr(sconn->sock, addr, sizeof(addr)),
188 (int)ret, strerror(errno) ));
190 srv_free_enc_buffer(sconn, buf_out);
191 goto out;
194 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
195 srv_free_enc_buffer(sconn, buf_out);
196 out:
197 SMB_PERFCOUNT_END(pcd);
199 smbd_unlock_socket(sconn);
200 return true;
203 /*******************************************************************
204 Setup the word count and byte count for a smb message.
205 ********************************************************************/
207 int srv_set_message(char *buf,
208 int num_words,
209 int num_bytes,
210 bool zero)
212 if (zero && (num_words || num_bytes)) {
213 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
215 SCVAL(buf,smb_wct,num_words);
216 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
217 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
218 return (smb_size + num_words*2 + num_bytes);
221 static bool valid_smb_header(struct smbd_server_connection *sconn,
222 const uint8_t *inbuf)
224 if (is_encrypted_packet(sconn, inbuf)) {
225 return true;
228 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
229 * but it just looks weird to call strncmp for this one.
231 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
234 /* Socket functions for smbd packet processing. */
236 static bool valid_packet_size(size_t len)
239 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
240 * of header. Don't print the error if this fits.... JRA.
243 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
244 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
245 (unsigned long)len));
246 return false;
248 return true;
251 static NTSTATUS read_packet_remainder(int fd, char *buffer,
252 unsigned int timeout, ssize_t len)
254 NTSTATUS status;
256 if (len <= 0) {
257 return NT_STATUS_OK;
260 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
261 if (!NT_STATUS_IS_OK(status)) {
262 char addr[INET6_ADDRSTRLEN];
263 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
264 "error = %s.\n",
265 get_peer_addr(fd, addr, sizeof(addr)),
266 nt_errstr(status)));
268 return status;
271 /****************************************************************************
272 Attempt a zerocopy writeX read. We know here that len > smb_size-4
273 ****************************************************************************/
276 * Unfortunately, earlier versions of smbclient/libsmbclient
277 * don't send this "standard" writeX header. I've fixed this
278 * for 3.2 but we'll use the old method with earlier versions.
279 * Windows and CIFSFS at least use this standard size. Not
280 * sure about MacOSX.
283 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
284 (2*14) + /* word count (including bcc) */ \
285 1 /* pad byte */)
287 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
288 const char lenbuf[4],
289 struct smbd_server_connection *sconn,
290 int sock,
291 char **buffer,
292 unsigned int timeout,
293 size_t *p_unread,
294 size_t *len_ret)
296 /* Size of a WRITEX call (+4 byte len). */
297 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
298 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
299 ssize_t toread;
300 NTSTATUS status;
302 memcpy(writeX_header, lenbuf, 4);
304 status = read_fd_with_timeout(
305 sock, writeX_header + 4,
306 STANDARD_WRITE_AND_X_HEADER_SIZE,
307 STANDARD_WRITE_AND_X_HEADER_SIZE,
308 timeout, NULL);
310 if (!NT_STATUS_IS_OK(status)) {
311 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
312 "error = %s.\n",
313 tsocket_address_string(sconn->remote_address,
314 talloc_tos()),
315 nt_errstr(status)));
316 return status;
320 * Ok - now try and see if this is a possible
321 * valid writeX call.
324 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
326 * If the data offset is beyond what
327 * we've read, drain the extra bytes.
329 uint16_t doff = SVAL(writeX_header,smb_vwv11);
330 ssize_t newlen;
332 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
333 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
334 if (drain_socket(sock, drain) != drain) {
335 smb_panic("receive_smb_raw_talloc_partial_read:"
336 " failed to drain pending bytes");
338 } else {
339 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
342 /* Spoof down the length and null out the bcc. */
343 set_message_bcc(writeX_header, 0);
344 newlen = smb_len(writeX_header);
346 /* Copy the header we've written. */
348 *buffer = (char *)talloc_memdup(mem_ctx,
349 writeX_header,
350 sizeof(writeX_header));
352 if (*buffer == NULL) {
353 DEBUG(0, ("Could not allocate inbuf of length %d\n",
354 (int)sizeof(writeX_header)));
355 return NT_STATUS_NO_MEMORY;
358 /* Work out the remaining bytes. */
359 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
360 *len_ret = newlen + 4;
361 return NT_STATUS_OK;
364 if (!valid_packet_size(len)) {
365 return NT_STATUS_INVALID_PARAMETER;
369 * Not a valid writeX call. Just do the standard
370 * talloc and return.
373 *buffer = talloc_array(mem_ctx, char, len+4);
375 if (*buffer == NULL) {
376 DEBUG(0, ("Could not allocate inbuf of length %d\n",
377 (int)len+4));
378 return NT_STATUS_NO_MEMORY;
381 /* Copy in what we already read. */
382 memcpy(*buffer,
383 writeX_header,
384 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
385 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
387 if(toread > 0) {
388 status = read_packet_remainder(
389 sock,
390 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
391 timeout, toread);
393 if (!NT_STATUS_IS_OK(status)) {
394 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
395 nt_errstr(status)));
396 return status;
400 *len_ret = len + 4;
401 return NT_STATUS_OK;
404 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
405 struct smbd_server_connection *sconn,
406 int sock,
407 char **buffer, unsigned int timeout,
408 size_t *p_unread, size_t *plen)
410 char lenbuf[4];
411 size_t len;
412 int min_recv_size = lp_min_receive_file_size();
413 NTSTATUS status;
415 *p_unread = 0;
417 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
418 &len);
419 if (!NT_STATUS_IS_OK(status)) {
420 return status;
423 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
424 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
425 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
426 !srv_is_signing_active(sconn) &&
427 sconn->smb1.echo_handler.trusted_fde == NULL) {
429 return receive_smb_raw_talloc_partial_read(
430 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
431 p_unread, plen);
434 if (!valid_packet_size(len)) {
435 return NT_STATUS_INVALID_PARAMETER;
439 * The +4 here can't wrap, we've checked the length above already.
442 *buffer = talloc_array(mem_ctx, char, len+4);
444 if (*buffer == NULL) {
445 DEBUG(0, ("Could not allocate inbuf of length %d\n",
446 (int)len+4));
447 return NT_STATUS_NO_MEMORY;
450 memcpy(*buffer, lenbuf, sizeof(lenbuf));
452 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
453 if (!NT_STATUS_IS_OK(status)) {
454 return status;
457 *plen = len + 4;
458 return NT_STATUS_OK;
461 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
462 struct smbd_server_connection *sconn,
463 int sock,
464 char **buffer, unsigned int timeout,
465 size_t *p_unread, bool *p_encrypted,
466 size_t *p_len,
467 uint32_t *seqnum,
468 bool trusted_channel)
470 size_t len = 0;
471 NTSTATUS status;
473 *p_encrypted = false;
475 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
476 p_unread, &len);
477 if (!NT_STATUS_IS_OK(status)) {
478 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
479 ("receive_smb_raw_talloc failed for client %s "
480 "read error = %s.\n",
481 tsocket_address_string(sconn->remote_address,
482 talloc_tos()),
483 nt_errstr(status)) );
484 return status;
487 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
488 status = srv_decrypt_buffer(sconn, *buffer);
489 if (!NT_STATUS_IS_OK(status)) {
490 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
491 "incoming packet! Error %s\n",
492 nt_errstr(status) ));
493 return status;
495 *p_encrypted = true;
498 /* Check the incoming SMB signature. */
499 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
500 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
501 "incoming packet!\n"));
502 return NT_STATUS_INVALID_NETWORK_RESPONSE;
505 *p_len = len;
506 return NT_STATUS_OK;
510 * Initialize a struct smb_request from an inbuf
513 static bool init_smb_request(struct smb_request *req,
514 struct smbd_server_connection *sconn,
515 const uint8 *inbuf,
516 size_t unread_bytes, bool encrypted,
517 uint32_t seqnum)
519 struct smbXsrv_tcon *tcon;
520 NTSTATUS status;
521 NTTIME now;
522 size_t req_size = smb_len(inbuf) + 4;
524 /* Ensure we have at least smb_size bytes. */
525 if (req_size < smb_size) {
526 DEBUG(0,("init_smb_request: invalid request size %u\n",
527 (unsigned int)req_size ));
528 return false;
531 req->request_time = timeval_current();
532 now = timeval_to_nttime(&req->request_time);
534 req->cmd = CVAL(inbuf, smb_com);
535 req->flags2 = SVAL(inbuf, smb_flg2);
536 req->smbpid = SVAL(inbuf, smb_pid);
537 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
538 req->seqnum = seqnum;
539 req->vuid = SVAL(inbuf, smb_uid);
540 req->tid = SVAL(inbuf, smb_tid);
541 req->wct = CVAL(inbuf, smb_wct);
542 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
543 req->buflen = smb_buflen(inbuf);
544 req->buf = (const uint8_t *)smb_buf_const(inbuf);
545 req->unread_bytes = unread_bytes;
546 req->encrypted = encrypted;
547 req->sconn = sconn;
548 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
549 if (NT_STATUS_IS_OK(status)) {
550 req->conn = tcon->compat;
551 } else {
552 req->conn = NULL;
554 req->chain_fsp = NULL;
555 req->smb2req = NULL;
556 req->priv_paths = NULL;
557 req->chain = NULL;
558 smb_init_perfcount_data(&req->pcd);
560 /* Ensure we have at least wct words and 2 bytes of bcc. */
561 if (smb_size + req->wct*2 > req_size) {
562 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
563 (unsigned int)req->wct,
564 (unsigned int)req_size));
565 return false;
567 /* Ensure bcc is correct. */
568 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
569 DEBUG(0,("init_smb_request: invalid bcc number %u "
570 "(wct = %u, size %u)\n",
571 (unsigned int)req->buflen,
572 (unsigned int)req->wct,
573 (unsigned int)req_size));
574 return false;
577 req->outbuf = NULL;
578 return true;
581 static void process_smb(struct smbd_server_connection *conn,
582 uint8_t *inbuf, size_t nread, size_t unread_bytes,
583 uint32_t seqnum, bool encrypted,
584 struct smb_perfcount_data *deferred_pcd);
586 static void smbd_deferred_open_timer(struct event_context *ev,
587 struct timed_event *te,
588 struct timeval _tval,
589 void *private_data)
591 struct pending_message_list *msg = talloc_get_type(private_data,
592 struct pending_message_list);
593 struct smbd_server_connection *sconn = msg->sconn;
594 TALLOC_CTX *mem_ctx = talloc_tos();
595 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
596 uint8_t *inbuf;
598 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
599 msg->buf.length);
600 if (inbuf == NULL) {
601 exit_server("smbd_deferred_open_timer: talloc failed\n");
602 return;
605 /* We leave this message on the queue so the open code can
606 know this is a retry. */
607 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
608 (unsigned long long)mid ));
610 /* Mark the message as processed so this is not
611 * re-processed in error. */
612 msg->processed = true;
614 process_smb(sconn, inbuf,
615 msg->buf.length, 0,
616 msg->seqnum, msg->encrypted, &msg->pcd);
618 /* If it's still there and was processed, remove it. */
619 msg = get_deferred_open_message_smb(sconn, mid);
620 if (msg && msg->processed) {
621 remove_deferred_open_message_smb(sconn, mid);
625 /****************************************************************************
626 Function to push a message onto the tail of a linked list of smb messages ready
627 for processing.
628 ****************************************************************************/
630 static bool push_queued_message(struct smb_request *req,
631 struct timeval request_time,
632 struct timeval end_time,
633 char *private_data, size_t private_len)
635 int msg_len = smb_len(req->inbuf) + 4;
636 struct pending_message_list *msg;
638 msg = talloc_zero(NULL, struct pending_message_list);
640 if(msg == NULL) {
641 DEBUG(0,("push_message: malloc fail (1)\n"));
642 return False;
644 msg->sconn = req->sconn;
646 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
647 if(msg->buf.data == NULL) {
648 DEBUG(0,("push_message: malloc fail (2)\n"));
649 TALLOC_FREE(msg);
650 return False;
653 msg->request_time = request_time;
654 msg->seqnum = req->seqnum;
655 msg->encrypted = req->encrypted;
656 msg->processed = false;
657 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
659 if (private_data) {
660 msg->private_data = data_blob_talloc(msg, private_data,
661 private_len);
662 if (msg->private_data.data == NULL) {
663 DEBUG(0,("push_message: malloc fail (3)\n"));
664 TALLOC_FREE(msg);
665 return False;
669 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
670 msg,
671 end_time,
672 smbd_deferred_open_timer,
673 msg);
674 if (!msg->te) {
675 DEBUG(0,("push_message: event_add_timed failed\n"));
676 TALLOC_FREE(msg);
677 return false;
680 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
681 struct pending_message_list *);
683 DEBUG(10,("push_message: pushed message length %u on "
684 "deferred_open_queue\n", (unsigned int)msg_len));
686 return True;
689 /****************************************************************************
690 Function to delete a sharing violation open message by mid.
691 ****************************************************************************/
693 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
694 uint64_t mid)
696 struct pending_message_list *pml;
698 if (sconn->using_smb2) {
699 remove_deferred_open_message_smb2(sconn, mid);
700 return;
703 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
704 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
705 DEBUG(10,("remove_deferred_open_message_smb: "
706 "deleting mid %llu len %u\n",
707 (unsigned long long)mid,
708 (unsigned int)pml->buf.length ));
709 DLIST_REMOVE(sconn->deferred_open_queue, pml);
710 TALLOC_FREE(pml);
711 return;
716 /****************************************************************************
717 Move a sharing violation open retry message to the front of the list and
718 schedule it for immediate processing.
719 ****************************************************************************/
721 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
722 uint64_t mid)
724 struct pending_message_list *pml;
725 int i = 0;
727 if (sconn->using_smb2) {
728 schedule_deferred_open_message_smb2(sconn, mid);
729 return;
732 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
733 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
735 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
736 "msg_mid = %llu\n",
737 i++,
738 (unsigned long long)msg_mid ));
740 if (mid == msg_mid) {
741 struct timed_event *te;
743 if (pml->processed) {
744 /* A processed message should not be
745 * rescheduled. */
746 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
747 "message mid %llu was already processed\n",
748 (unsigned long long)msg_mid ));
749 continue;
752 DEBUG(10,("schedule_deferred_open_message_smb: "
753 "scheduling mid %llu\n",
754 (unsigned long long)mid ));
756 te = tevent_add_timer(pml->sconn->ev_ctx,
757 pml,
758 timeval_zero(),
759 smbd_deferred_open_timer,
760 pml);
761 if (!te) {
762 DEBUG(10,("schedule_deferred_open_message_smb: "
763 "event_add_timed() failed, "
764 "skipping mid %llu\n",
765 (unsigned long long)msg_mid ));
768 TALLOC_FREE(pml->te);
769 pml->te = te;
770 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
771 return;
775 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
776 "find message mid %llu\n",
777 (unsigned long long)mid ));
780 /****************************************************************************
781 Return true if this mid is on the deferred queue and was not yet processed.
782 ****************************************************************************/
784 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
786 struct pending_message_list *pml;
788 if (sconn->using_smb2) {
789 return open_was_deferred_smb2(sconn, mid);
792 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
793 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
794 return True;
797 return False;
800 /****************************************************************************
801 Return the message queued by this mid.
802 ****************************************************************************/
804 static struct pending_message_list *get_deferred_open_message_smb(
805 struct smbd_server_connection *sconn, uint64_t mid)
807 struct pending_message_list *pml;
809 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
810 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
811 return pml;
814 return NULL;
817 /****************************************************************************
818 Get the state data queued by this mid.
819 ****************************************************************************/
821 bool get_deferred_open_message_state(struct smb_request *smbreq,
822 struct timeval *p_request_time,
823 void **pp_state)
825 struct pending_message_list *pml;
827 if (smbreq->sconn->using_smb2) {
828 return get_deferred_open_message_state_smb2(smbreq->smb2req,
829 p_request_time,
830 pp_state);
833 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
834 if (!pml) {
835 return false;
837 if (p_request_time) {
838 *p_request_time = pml->request_time;
840 if (pp_state) {
841 *pp_state = (void *)pml->private_data.data;
843 return true;
846 /****************************************************************************
847 Function to push a deferred open smb message onto a linked list of local smb
848 messages ready for processing.
849 ****************************************************************************/
851 bool push_deferred_open_message_smb(struct smb_request *req,
852 struct timeval request_time,
853 struct timeval timeout,
854 struct file_id id,
855 char *private_data, size_t priv_len)
857 struct timeval end_time;
859 if (req->smb2req) {
860 return push_deferred_open_message_smb2(req->smb2req,
861 request_time,
862 timeout,
864 private_data,
865 priv_len);
868 if (req->unread_bytes) {
869 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
870 "unread_bytes = %u\n",
871 (unsigned int)req->unread_bytes ));
872 smb_panic("push_deferred_open_message_smb: "
873 "logic error unread_bytes != 0" );
876 end_time = timeval_sum(&request_time, &timeout);
878 DEBUG(10,("push_deferred_open_message_smb: pushing message "
879 "len %u mid %llu timeout time [%u.%06u]\n",
880 (unsigned int) smb_len(req->inbuf)+4,
881 (unsigned long long)req->mid,
882 (unsigned int)end_time.tv_sec,
883 (unsigned int)end_time.tv_usec));
885 return push_queued_message(req, request_time, end_time,
886 private_data, priv_len);
889 static void smbd_sig_term_handler(struct tevent_context *ev,
890 struct tevent_signal *se,
891 int signum,
892 int count,
893 void *siginfo,
894 void *private_data)
896 exit_server_cleanly("termination signal");
899 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
901 struct tevent_signal *se;
903 se = tevent_add_signal(sconn->ev_ctx,
904 sconn,
905 SIGTERM, 0,
906 smbd_sig_term_handler,
907 sconn);
908 if (!se) {
909 exit_server("failed to setup SIGTERM handler");
913 static void smbd_sig_hup_handler(struct tevent_context *ev,
914 struct tevent_signal *se,
915 int signum,
916 int count,
917 void *siginfo,
918 void *private_data)
920 struct smbd_server_connection *sconn =
921 talloc_get_type_abort(private_data,
922 struct smbd_server_connection);
924 change_to_root_user();
925 DEBUG(1,("Reloading services after SIGHUP\n"));
926 reload_services(sconn, conn_snum_used, false);
929 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
931 struct tevent_signal *se;
933 se = tevent_add_signal(sconn->ev_ctx,
934 sconn,
935 SIGHUP, 0,
936 smbd_sig_hup_handler,
937 sconn);
938 if (!se) {
939 exit_server("failed to setup SIGHUP handler");
943 static void smbd_conf_updated(struct messaging_context *msg,
944 void *private_data,
945 uint32_t msg_type,
946 struct server_id server_id,
947 DATA_BLOB *data)
949 struct smbd_server_connection *sconn =
950 talloc_get_type_abort(private_data,
951 struct smbd_server_connection);
953 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
954 "updated. Reloading.\n"));
955 change_to_root_user();
956 reload_services(sconn, conn_snum_used, false);
960 * Only allow 5 outstanding trans requests. We're allocating memory, so
961 * prevent a DoS.
964 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
966 int count = 0;
967 for (; list != NULL; list = list->next) {
969 if (list->mid == mid) {
970 return NT_STATUS_INVALID_PARAMETER;
973 count += 1;
975 if (count > 5) {
976 return NT_STATUS_INSUFFICIENT_RESOURCES;
979 return NT_STATUS_OK;
983 These flags determine some of the permissions required to do an operation
985 Note that I don't set NEED_WRITE on some write operations because they
986 are used by some brain-dead clients when printing, and I don't want to
987 force write permissions on print services.
989 #define AS_USER (1<<0)
990 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
991 #define TIME_INIT (1<<2)
992 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
993 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
994 #define DO_CHDIR (1<<6)
997 define a list of possible SMB messages and their corresponding
998 functions. Any message that has a NULL function is unimplemented -
999 please feel free to contribute implementations!
1001 static const struct smb_message_struct {
1002 const char *name;
1003 void (*fn)(struct smb_request *req);
1004 int flags;
1005 } smb_messages[256] = {
1007 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1008 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1009 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1010 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1011 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1012 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1013 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1014 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1015 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1016 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1017 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1018 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1019 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1020 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1021 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1022 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1023 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1024 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1025 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1026 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1027 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1028 /* 0x15 */ { NULL, NULL, 0 },
1029 /* 0x16 */ { NULL, NULL, 0 },
1030 /* 0x17 */ { NULL, NULL, 0 },
1031 /* 0x18 */ { NULL, NULL, 0 },
1032 /* 0x19 */ { NULL, NULL, 0 },
1033 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1034 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1035 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1036 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1037 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1038 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1039 /* 0x20 */ { "SMBwritec", NULL,0},
1040 /* 0x21 */ { NULL, NULL, 0 },
1041 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1042 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1043 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1044 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1045 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1046 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1047 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1048 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1049 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1050 /* 0x2b */ { "SMBecho",reply_echo,0},
1051 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1052 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1053 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1054 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1055 /* 0x30 */ { NULL, NULL, 0 },
1056 /* 0x31 */ { NULL, NULL, 0 },
1057 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1058 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1059 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1060 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1061 /* 0x36 */ { NULL, NULL, 0 },
1062 /* 0x37 */ { NULL, NULL, 0 },
1063 /* 0x38 */ { NULL, NULL, 0 },
1064 /* 0x39 */ { NULL, NULL, 0 },
1065 /* 0x3a */ { NULL, NULL, 0 },
1066 /* 0x3b */ { NULL, NULL, 0 },
1067 /* 0x3c */ { NULL, NULL, 0 },
1068 /* 0x3d */ { NULL, NULL, 0 },
1069 /* 0x3e */ { NULL, NULL, 0 },
1070 /* 0x3f */ { NULL, NULL, 0 },
1071 /* 0x40 */ { NULL, NULL, 0 },
1072 /* 0x41 */ { NULL, NULL, 0 },
1073 /* 0x42 */ { NULL, NULL, 0 },
1074 /* 0x43 */ { NULL, NULL, 0 },
1075 /* 0x44 */ { NULL, NULL, 0 },
1076 /* 0x45 */ { NULL, NULL, 0 },
1077 /* 0x46 */ { NULL, NULL, 0 },
1078 /* 0x47 */ { NULL, NULL, 0 },
1079 /* 0x48 */ { NULL, NULL, 0 },
1080 /* 0x49 */ { NULL, NULL, 0 },
1081 /* 0x4a */ { NULL, NULL, 0 },
1082 /* 0x4b */ { NULL, NULL, 0 },
1083 /* 0x4c */ { NULL, NULL, 0 },
1084 /* 0x4d */ { NULL, NULL, 0 },
1085 /* 0x4e */ { NULL, NULL, 0 },
1086 /* 0x4f */ { NULL, NULL, 0 },
1087 /* 0x50 */ { NULL, NULL, 0 },
1088 /* 0x51 */ { NULL, NULL, 0 },
1089 /* 0x52 */ { NULL, NULL, 0 },
1090 /* 0x53 */ { NULL, NULL, 0 },
1091 /* 0x54 */ { NULL, NULL, 0 },
1092 /* 0x55 */ { NULL, NULL, 0 },
1093 /* 0x56 */ { NULL, NULL, 0 },
1094 /* 0x57 */ { NULL, NULL, 0 },
1095 /* 0x58 */ { NULL, NULL, 0 },
1096 /* 0x59 */ { NULL, NULL, 0 },
1097 /* 0x5a */ { NULL, NULL, 0 },
1098 /* 0x5b */ { NULL, NULL, 0 },
1099 /* 0x5c */ { NULL, NULL, 0 },
1100 /* 0x5d */ { NULL, NULL, 0 },
1101 /* 0x5e */ { NULL, NULL, 0 },
1102 /* 0x5f */ { NULL, NULL, 0 },
1103 /* 0x60 */ { NULL, NULL, 0 },
1104 /* 0x61 */ { NULL, NULL, 0 },
1105 /* 0x62 */ { NULL, NULL, 0 },
1106 /* 0x63 */ { NULL, NULL, 0 },
1107 /* 0x64 */ { NULL, NULL, 0 },
1108 /* 0x65 */ { NULL, NULL, 0 },
1109 /* 0x66 */ { NULL, NULL, 0 },
1110 /* 0x67 */ { NULL, NULL, 0 },
1111 /* 0x68 */ { NULL, NULL, 0 },
1112 /* 0x69 */ { NULL, NULL, 0 },
1113 /* 0x6a */ { NULL, NULL, 0 },
1114 /* 0x6b */ { NULL, NULL, 0 },
1115 /* 0x6c */ { NULL, NULL, 0 },
1116 /* 0x6d */ { NULL, NULL, 0 },
1117 /* 0x6e */ { NULL, NULL, 0 },
1118 /* 0x6f */ { NULL, NULL, 0 },
1119 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1120 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1121 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1122 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1123 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1124 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1125 /* 0x76 */ { NULL, NULL, 0 },
1126 /* 0x77 */ { NULL, NULL, 0 },
1127 /* 0x78 */ { NULL, NULL, 0 },
1128 /* 0x79 */ { NULL, NULL, 0 },
1129 /* 0x7a */ { NULL, NULL, 0 },
1130 /* 0x7b */ { NULL, NULL, 0 },
1131 /* 0x7c */ { NULL, NULL, 0 },
1132 /* 0x7d */ { NULL, NULL, 0 },
1133 /* 0x7e */ { NULL, NULL, 0 },
1134 /* 0x7f */ { NULL, NULL, 0 },
1135 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1136 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1137 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1138 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1139 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1140 /* 0x85 */ { NULL, NULL, 0 },
1141 /* 0x86 */ { NULL, NULL, 0 },
1142 /* 0x87 */ { NULL, NULL, 0 },
1143 /* 0x88 */ { NULL, NULL, 0 },
1144 /* 0x89 */ { NULL, NULL, 0 },
1145 /* 0x8a */ { NULL, NULL, 0 },
1146 /* 0x8b */ { NULL, NULL, 0 },
1147 /* 0x8c */ { NULL, NULL, 0 },
1148 /* 0x8d */ { NULL, NULL, 0 },
1149 /* 0x8e */ { NULL, NULL, 0 },
1150 /* 0x8f */ { NULL, NULL, 0 },
1151 /* 0x90 */ { NULL, NULL, 0 },
1152 /* 0x91 */ { NULL, NULL, 0 },
1153 /* 0x92 */ { NULL, NULL, 0 },
1154 /* 0x93 */ { NULL, NULL, 0 },
1155 /* 0x94 */ { NULL, NULL, 0 },
1156 /* 0x95 */ { NULL, NULL, 0 },
1157 /* 0x96 */ { NULL, NULL, 0 },
1158 /* 0x97 */ { NULL, NULL, 0 },
1159 /* 0x98 */ { NULL, NULL, 0 },
1160 /* 0x99 */ { NULL, NULL, 0 },
1161 /* 0x9a */ { NULL, NULL, 0 },
1162 /* 0x9b */ { NULL, NULL, 0 },
1163 /* 0x9c */ { NULL, NULL, 0 },
1164 /* 0x9d */ { NULL, NULL, 0 },
1165 /* 0x9e */ { NULL, NULL, 0 },
1166 /* 0x9f */ { NULL, NULL, 0 },
1167 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1168 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1169 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1170 /* 0xa3 */ { NULL, NULL, 0 },
1171 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1172 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1173 /* 0xa6 */ { NULL, NULL, 0 },
1174 /* 0xa7 */ { NULL, NULL, 0 },
1175 /* 0xa8 */ { NULL, NULL, 0 },
1176 /* 0xa9 */ { NULL, NULL, 0 },
1177 /* 0xaa */ { NULL, NULL, 0 },
1178 /* 0xab */ { NULL, NULL, 0 },
1179 /* 0xac */ { NULL, NULL, 0 },
1180 /* 0xad */ { NULL, NULL, 0 },
1181 /* 0xae */ { NULL, NULL, 0 },
1182 /* 0xaf */ { NULL, NULL, 0 },
1183 /* 0xb0 */ { NULL, NULL, 0 },
1184 /* 0xb1 */ { NULL, NULL, 0 },
1185 /* 0xb2 */ { NULL, NULL, 0 },
1186 /* 0xb3 */ { NULL, NULL, 0 },
1187 /* 0xb4 */ { NULL, NULL, 0 },
1188 /* 0xb5 */ { NULL, NULL, 0 },
1189 /* 0xb6 */ { NULL, NULL, 0 },
1190 /* 0xb7 */ { NULL, NULL, 0 },
1191 /* 0xb8 */ { NULL, NULL, 0 },
1192 /* 0xb9 */ { NULL, NULL, 0 },
1193 /* 0xba */ { NULL, NULL, 0 },
1194 /* 0xbb */ { NULL, NULL, 0 },
1195 /* 0xbc */ { NULL, NULL, 0 },
1196 /* 0xbd */ { NULL, NULL, 0 },
1197 /* 0xbe */ { NULL, NULL, 0 },
1198 /* 0xbf */ { NULL, NULL, 0 },
1199 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1200 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1201 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1202 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1203 /* 0xc4 */ { NULL, NULL, 0 },
1204 /* 0xc5 */ { NULL, NULL, 0 },
1205 /* 0xc6 */ { NULL, NULL, 0 },
1206 /* 0xc7 */ { NULL, NULL, 0 },
1207 /* 0xc8 */ { NULL, NULL, 0 },
1208 /* 0xc9 */ { NULL, NULL, 0 },
1209 /* 0xca */ { NULL, NULL, 0 },
1210 /* 0xcb */ { NULL, NULL, 0 },
1211 /* 0xcc */ { NULL, NULL, 0 },
1212 /* 0xcd */ { NULL, NULL, 0 },
1213 /* 0xce */ { NULL, NULL, 0 },
1214 /* 0xcf */ { NULL, NULL, 0 },
1215 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1216 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1217 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1218 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1219 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1220 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1221 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1222 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1223 /* 0xd8 */ { NULL, NULL, 0 },
1224 /* 0xd9 */ { NULL, NULL, 0 },
1225 /* 0xda */ { NULL, NULL, 0 },
1226 /* 0xdb */ { NULL, NULL, 0 },
1227 /* 0xdc */ { NULL, NULL, 0 },
1228 /* 0xdd */ { NULL, NULL, 0 },
1229 /* 0xde */ { NULL, NULL, 0 },
1230 /* 0xdf */ { NULL, NULL, 0 },
1231 /* 0xe0 */ { NULL, NULL, 0 },
1232 /* 0xe1 */ { NULL, NULL, 0 },
1233 /* 0xe2 */ { NULL, NULL, 0 },
1234 /* 0xe3 */ { NULL, NULL, 0 },
1235 /* 0xe4 */ { NULL, NULL, 0 },
1236 /* 0xe5 */ { NULL, NULL, 0 },
1237 /* 0xe6 */ { NULL, NULL, 0 },
1238 /* 0xe7 */ { NULL, NULL, 0 },
1239 /* 0xe8 */ { NULL, NULL, 0 },
1240 /* 0xe9 */ { NULL, NULL, 0 },
1241 /* 0xea */ { NULL, NULL, 0 },
1242 /* 0xeb */ { NULL, NULL, 0 },
1243 /* 0xec */ { NULL, NULL, 0 },
1244 /* 0xed */ { NULL, NULL, 0 },
1245 /* 0xee */ { NULL, NULL, 0 },
1246 /* 0xef */ { NULL, NULL, 0 },
1247 /* 0xf0 */ { NULL, NULL, 0 },
1248 /* 0xf1 */ { NULL, NULL, 0 },
1249 /* 0xf2 */ { NULL, NULL, 0 },
1250 /* 0xf3 */ { NULL, NULL, 0 },
1251 /* 0xf4 */ { NULL, NULL, 0 },
1252 /* 0xf5 */ { NULL, NULL, 0 },
1253 /* 0xf6 */ { NULL, NULL, 0 },
1254 /* 0xf7 */ { NULL, NULL, 0 },
1255 /* 0xf8 */ { NULL, NULL, 0 },
1256 /* 0xf9 */ { NULL, NULL, 0 },
1257 /* 0xfa */ { NULL, NULL, 0 },
1258 /* 0xfb */ { NULL, NULL, 0 },
1259 /* 0xfc */ { NULL, NULL, 0 },
1260 /* 0xfd */ { NULL, NULL, 0 },
1261 /* 0xfe */ { NULL, NULL, 0 },
1262 /* 0xff */ { NULL, NULL, 0 }
1266 /*******************************************************************
1267 allocate and initialize a reply packet
1268 ********************************************************************/
1270 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1271 const char *inbuf, char **outbuf, uint8_t num_words,
1272 uint32_t num_bytes)
1275 * Protect against integer wrap
1277 if ((num_bytes > 0xffffff)
1278 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1279 char *msg;
1280 if (asprintf(&msg, "num_bytes too large: %u",
1281 (unsigned)num_bytes) == -1) {
1282 msg = discard_const_p(char, "num_bytes too large");
1284 smb_panic(msg);
1287 *outbuf = talloc_array(mem_ctx, char,
1288 smb_size + num_words*2 + num_bytes);
1289 if (*outbuf == NULL) {
1290 return false;
1293 construct_reply_common(req, inbuf, *outbuf);
1294 srv_set_message(*outbuf, num_words, num_bytes, false);
1296 * Zero out the word area, the caller has to take care of the bcc area
1297 * himself
1299 if (num_words != 0) {
1300 memset(*outbuf + smb_vwv0, 0, num_words*2);
1303 return true;
1306 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1308 char *outbuf;
1309 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1310 num_bytes)) {
1311 smb_panic("could not allocate output buffer\n");
1313 req->outbuf = (uint8_t *)outbuf;
1317 /*******************************************************************
1318 Dump a packet to a file.
1319 ********************************************************************/
1321 static void smb_dump(const char *name, int type, const char *data)
1323 size_t len;
1324 int fd, i;
1325 char *fname = NULL;
1326 if (DEBUGLEVEL < 50) {
1327 return;
1330 len = smb_len_tcp(data)+4;
1331 for (i=1;i<100;i++) {
1332 fname = talloc_asprintf(talloc_tos(),
1333 "/tmp/%s.%d.%s",
1334 name,
1336 type ? "req" : "resp");
1337 if (fname == NULL) {
1338 return;
1340 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1341 if (fd != -1 || errno != EEXIST) break;
1342 TALLOC_FREE(fname);
1344 if (fd != -1) {
1345 ssize_t ret = write(fd, data, len);
1346 if (ret != len)
1347 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1348 close(fd);
1349 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1351 TALLOC_FREE(fname);
1354 /****************************************************************************
1355 Prepare everything for calling the actual request function, and potentially
1356 call the request function via the "new" interface.
1358 Return False if the "legacy" function needs to be called, everything is
1359 prepared.
1361 Return True if we're done.
1363 I know this API sucks, but it is the one with the least code change I could
1364 find.
1365 ****************************************************************************/
1367 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1369 int flags;
1370 uint64_t session_tag;
1371 connection_struct *conn = NULL;
1372 struct smbd_server_connection *sconn = req->sconn;
1373 NTTIME now = timeval_to_nttime(&req->request_time);
1374 struct smbXsrv_session *session = NULL;
1375 NTSTATUS status;
1377 errno = 0;
1379 if (smb_messages[type].fn == NULL) {
1380 DEBUG(0,("Unknown message type %d!\n",type));
1381 smb_dump("Unknown", 1, (const char *)req->inbuf);
1382 reply_unknown_new(req, type);
1383 return NULL;
1386 flags = smb_messages[type].flags;
1388 /* In share mode security we must ignore the vuid. */
1389 session_tag = req->vuid;
1390 conn = req->conn;
1392 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1393 (int)getpid(), (unsigned long)conn));
1395 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1397 /* Ensure this value is replaced in the incoming packet. */
1398 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1401 * Ensure the correct username is in current_user_info. This is a
1402 * really ugly bugfix for problems with multiple session_setup_and_X's
1403 * being done and allowing %U and %G substitutions to work correctly.
1404 * There is a reason this code is done here, don't move it unless you
1405 * know what you're doing... :-).
1406 * JRA.
1410 * lookup an existing session
1412 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1413 * here, the main check is still in change_to_user()
1415 status = smb1srv_session_lookup(sconn->conn,
1416 session_tag,
1417 now,
1418 &session);
1419 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1420 switch (type) {
1421 case SMBsesssetupX:
1422 status = NT_STATUS_OK;
1423 break;
1424 default:
1425 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1426 (unsigned long long)session_tag,
1427 (unsigned long long)req->mid));
1428 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1429 return conn;
1433 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1434 struct user_struct *vuser = NULL;
1436 sconn->smb1.sessions.last_session_tag = session_tag;
1437 if (session) {
1438 vuser = session->compat;
1440 if (vuser) {
1441 set_current_user_info(
1442 vuser->session_info->unix_info->sanitized_username,
1443 vuser->session_info->unix_info->unix_name,
1444 vuser->session_info->info->domain_name);
1448 /* Does this call need to be run as the connected user? */
1449 if (flags & AS_USER) {
1451 /* Does this call need a valid tree connection? */
1452 if (!conn) {
1454 * Amazingly, the error code depends on the command
1455 * (from Samba4).
1457 if (type == SMBntcreateX) {
1458 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1459 } else {
1460 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1462 return NULL;
1465 if (!change_to_user(conn,session_tag)) {
1466 DEBUG(0, ("Error: Could not change to user. Removing "
1467 "deferred open, mid=%llu.\n",
1468 (unsigned long long)req->mid));
1469 reply_force_doserror(req, ERRSRV, ERRbaduid);
1470 return conn;
1473 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1475 /* Does it need write permission? */
1476 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1477 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1478 return conn;
1481 /* IPC services are limited */
1482 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1483 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1484 return conn;
1486 } else {
1487 /* This call needs to be run as root */
1488 change_to_root_user();
1491 /* load service specific parameters */
1492 if (conn) {
1493 if (req->encrypted) {
1494 conn->encrypted_tid = true;
1495 /* encrypted required from now on. */
1496 conn->encrypt_level = Required;
1497 } else if (ENCRYPTION_REQUIRED(conn)) {
1498 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1499 exit_server_cleanly("encryption required "
1500 "on connection");
1501 return conn;
1505 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1506 (flags & (AS_USER|DO_CHDIR)
1507 ?True:False))) {
1508 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 return conn;
1511 conn->num_smb_operations++;
1515 * Does this protocol need to be run as guest? (Only archane
1516 * messenger service requests have this...)
1518 if (flags & AS_GUEST) {
1519 char *raddr;
1520 bool ok;
1522 if (!change_to_guest()) {
1523 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1524 return conn;
1527 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1528 talloc_tos());
1529 if (raddr == NULL) {
1530 reply_nterror(req, NT_STATUS_NO_MEMORY);
1531 return conn;
1535 * Haven't we checked this in smbd_process already???
1538 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1539 sconn->remote_hostname, raddr);
1540 TALLOC_FREE(raddr);
1542 if (!ok) {
1543 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1544 return conn;
1548 smb_messages[type].fn(req);
1549 return req->conn;
1552 /****************************************************************************
1553 Construct a reply to the incoming packet.
1554 ****************************************************************************/
1556 static void construct_reply(struct smbd_server_connection *sconn,
1557 char *inbuf, int size, size_t unread_bytes,
1558 uint32_t seqnum, bool encrypted,
1559 struct smb_perfcount_data *deferred_pcd)
1561 connection_struct *conn;
1562 struct smb_request *req;
1564 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1565 smb_panic("could not allocate smb_request");
1568 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1569 encrypted, seqnum)) {
1570 exit_server_cleanly("Invalid SMB request");
1573 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1575 /* we popped this message off the queue - keep original perf data */
1576 if (deferred_pcd)
1577 req->pcd = *deferred_pcd;
1578 else {
1579 SMB_PERFCOUNT_START(&req->pcd);
1580 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1581 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1584 conn = switch_message(req->cmd, req);
1586 if (req->outbuf == NULL) {
1587 return;
1590 if (CVAL(req->outbuf,0) == 0) {
1591 show_msg((char *)req->outbuf);
1594 if (!srv_send_smb(req->sconn,
1595 (char *)req->outbuf,
1596 true, req->seqnum+1,
1597 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1598 &req->pcd)) {
1599 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1602 TALLOC_FREE(req);
1604 return;
1607 static void construct_reply_chain(struct smbd_server_connection *sconn,
1608 char *inbuf, int size, uint32_t seqnum,
1609 bool encrypted,
1610 struct smb_perfcount_data *deferred_pcd)
1612 struct smb_request **reqs = NULL;
1613 struct smb_request *req;
1614 unsigned num_reqs;
1615 bool ok;
1617 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1618 seqnum, &reqs, &num_reqs);
1619 if (!ok) {
1620 char errbuf[smb_size];
1621 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1622 __LINE__, __FILE__);
1623 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1624 NULL)) {
1625 exit_server_cleanly("construct_reply_chain: "
1626 "srv_send_smb failed.");
1628 return;
1631 req = reqs[0];
1632 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1634 req->conn = switch_message(req->cmd, req);
1636 if (req->outbuf == NULL) {
1638 * Request has suspended itself, will come
1639 * back here.
1641 return;
1643 smb_request_done(req);
1647 * To be called from an async SMB handler that is potentially chained
1648 * when it is finished for shipping.
1651 void smb_request_done(struct smb_request *req)
1653 struct smb_request **reqs = NULL;
1654 struct smb_request *first_req;
1655 size_t i, num_reqs, next_index;
1656 NTSTATUS status;
1658 if (req->chain == NULL) {
1659 first_req = req;
1660 goto shipit;
1663 reqs = req->chain;
1664 num_reqs = talloc_array_length(reqs);
1666 for (i=0; i<num_reqs; i++) {
1667 if (reqs[i] == req) {
1668 break;
1671 if (i == num_reqs) {
1673 * Invalid chain, should not happen
1675 status = NT_STATUS_INTERNAL_ERROR;
1676 goto error;
1678 next_index = i+1;
1680 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1681 struct smb_request *next = reqs[next_index];
1682 struct smbXsrv_tcon *tcon;
1683 NTTIME now = timeval_to_nttime(&req->request_time);
1685 next->vuid = SVAL(req->outbuf, smb_uid);
1686 next->tid = SVAL(req->outbuf, smb_tid);
1687 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1688 now, &tcon);
1689 if (NT_STATUS_IS_OK(status)) {
1690 req->conn = tcon->compat;
1691 } else {
1692 req->conn = NULL;
1694 next->chain_fsp = req->chain_fsp;
1695 next->inbuf = (uint8_t *)req->inbuf;
1697 req = next;
1698 req->conn = switch_message(req->cmd, req);
1700 if (req->outbuf == NULL) {
1702 * Request has suspended itself, will come
1703 * back here.
1705 return;
1707 next_index += 1;
1710 first_req = reqs[0];
1712 for (i=1; i<next_index; i++) {
1713 bool ok;
1715 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1716 if (!ok) {
1717 status = NT_STATUS_INTERNAL_ERROR;
1718 goto error;
1722 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1723 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1726 * This scary statement intends to set the
1727 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1728 * to the value last_req->outbuf carries
1730 SSVAL(first_req->outbuf, smb_flg2,
1731 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1732 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1735 * Transfer the error codes from the subrequest to the main one
1737 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1738 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1740 _smb_setlen_large(
1741 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1743 shipit:
1744 if (!srv_send_smb(first_req->sconn,
1745 (char *)first_req->outbuf,
1746 true, first_req->seqnum+1,
1747 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1748 &first_req->pcd)) {
1749 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1750 "failed.");
1752 TALLOC_FREE(req); /* non-chained case */
1753 TALLOC_FREE(reqs); /* chained case */
1754 return;
1756 error:
1758 char errbuf[smb_size];
1759 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1760 if (!srv_send_smb(req->sconn, errbuf, true,
1761 req->seqnum+1, req->encrypted,
1762 NULL)) {
1763 exit_server_cleanly("construct_reply_chain: "
1764 "srv_send_smb failed.");
1767 TALLOC_FREE(req); /* non-chained case */
1768 TALLOC_FREE(reqs); /* chained case */
1771 /****************************************************************************
1772 Process an smb from the client
1773 ****************************************************************************/
1774 static void process_smb(struct smbd_server_connection *sconn,
1775 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1776 uint32_t seqnum, bool encrypted,
1777 struct smb_perfcount_data *deferred_pcd)
1779 int msg_type = CVAL(inbuf,0);
1781 DO_PROFILE_INC(smb_count);
1783 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1784 smb_len(inbuf) ) );
1785 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1786 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1788 if (msg_type != NBSSmessage) {
1790 * NetBIOS session request, keepalive, etc.
1792 reply_special(sconn, (char *)inbuf, nread);
1793 goto done;
1796 if (sconn->using_smb2) {
1797 /* At this point we're not really using smb2,
1798 * we make the decision here.. */
1799 if (smbd_is_smb2_header(inbuf, nread)) {
1800 smbd_smb2_first_negprot(sconn, inbuf, nread);
1801 return;
1802 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1803 && CVAL(inbuf, smb_com) != 0x72) {
1804 /* This is a non-negprot SMB1 packet.
1805 Disable SMB2 from now on. */
1806 sconn->using_smb2 = false;
1810 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1811 * so subtract 4 from it. */
1812 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1813 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1814 smb_len(inbuf)));
1816 /* special magic for immediate exit */
1817 if ((nread == 9) &&
1818 (IVAL(inbuf, 4) == 0x74697865) &&
1819 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1820 uint8_t exitcode = CVAL(inbuf, 8);
1821 DEBUG(1, ("Exiting immediately with code %d\n",
1822 (int)exitcode));
1823 exit(exitcode);
1826 exit_server_cleanly("Non-SMB packet");
1829 show_msg((char *)inbuf);
1831 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1832 construct_reply_chain(sconn, (char *)inbuf, nread,
1833 seqnum, encrypted, deferred_pcd);
1834 } else {
1835 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1836 seqnum, encrypted, deferred_pcd);
1839 sconn->trans_num++;
1841 done:
1842 sconn->num_requests++;
1844 /* The timeout_processing function isn't run nearly
1845 often enough to implement 'max log size' without
1846 overrunning the size of the file by many megabytes.
1847 This is especially true if we are running at debug
1848 level 10. Checking every 50 SMBs is a nice
1849 tradeoff of performance vs log file size overrun. */
1851 if ((sconn->num_requests % 50) == 0 &&
1852 need_to_check_log_size()) {
1853 change_to_root_user();
1854 check_log_size();
1858 /****************************************************************************
1859 Return a string containing the function name of a SMB command.
1860 ****************************************************************************/
1862 const char *smb_fn_name(int type)
1864 const char *unknown_name = "SMBunknown";
1866 if (smb_messages[type].name == NULL)
1867 return(unknown_name);
1869 return(smb_messages[type].name);
1872 /****************************************************************************
1873 Helper functions for contruct_reply.
1874 ****************************************************************************/
1876 void add_to_common_flags2(uint32 v)
1878 common_flags2 |= v;
1881 void remove_from_common_flags2(uint32 v)
1883 common_flags2 &= ~v;
1886 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1887 char *outbuf)
1889 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1890 uint16_t out_flags2 = common_flags2;
1892 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1893 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1894 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1896 srv_set_message(outbuf,0,0,false);
1898 SCVAL(outbuf, smb_com, req->cmd);
1899 SIVAL(outbuf,smb_rcls,0);
1900 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1901 SSVAL(outbuf,smb_flg2, out_flags2);
1902 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1903 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1905 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1906 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1907 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1908 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1911 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1913 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1917 * @brief Find the smb_cmd offset of the last command pushed
1918 * @param[in] buf The buffer we're building up
1919 * @retval Where can we put our next andx cmd?
1921 * While chaining requests, the "next" request we're looking at needs to put
1922 * its SMB_Command before the data the previous request already built up added
1923 * to the chain. Find the offset to the place where we have to put our cmd.
1926 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1928 uint8_t cmd;
1929 size_t ofs;
1931 cmd = CVAL(buf, smb_com);
1933 if (!is_andx_req(cmd)) {
1934 return false;
1937 ofs = smb_vwv0;
1939 while (CVAL(buf, ofs) != 0xff) {
1941 if (!is_andx_req(CVAL(buf, ofs))) {
1942 return false;
1946 * ofs is from start of smb header, so add the 4 length
1947 * bytes. The next cmd is right after the wct field.
1949 ofs = SVAL(buf, ofs+2) + 4 + 1;
1951 if (ofs+4 >= talloc_get_size(buf)) {
1952 return false;
1956 *pofs = ofs;
1957 return true;
1961 * @brief Do the smb chaining at a buffer level
1962 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1963 * @param[in] andx_buf Buffer to be appended
1966 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1968 uint8_t smb_command = CVAL(andx_buf, smb_com);
1969 uint8_t wct = CVAL(andx_buf, smb_wct);
1970 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1971 uint32_t num_bytes = smb_buflen(andx_buf);
1972 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1974 uint8_t *outbuf;
1975 size_t old_size, new_size;
1976 size_t ofs;
1977 size_t chain_padding = 0;
1978 size_t andx_cmd_ofs;
1981 old_size = talloc_get_size(*poutbuf);
1983 if ((old_size % 4) != 0) {
1985 * Align the wct field of subsequent requests to a 4-byte
1986 * boundary
1988 chain_padding = 4 - (old_size % 4);
1992 * After the old request comes the new wct field (1 byte), the vwv's
1993 * and the num_bytes field.
1996 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1997 new_size += num_bytes;
1999 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2000 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2001 (unsigned)new_size));
2002 return false;
2005 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2006 if (outbuf == NULL) {
2007 DEBUG(0, ("talloc failed\n"));
2008 return false;
2010 *poutbuf = outbuf;
2012 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2013 DEBUG(1, ("invalid command chain\n"));
2014 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2015 return false;
2018 if (chain_padding != 0) {
2019 memset(outbuf + old_size, 0, chain_padding);
2020 old_size += chain_padding;
2023 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2024 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2026 ofs = old_size;
2029 * Push the chained request:
2031 * wct field
2034 SCVAL(outbuf, ofs, wct);
2035 ofs += 1;
2038 * vwv array
2041 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2044 * HACK ALERT
2046 * Read&X has an offset into its data buffer at
2047 * vwv[6]. reply_read_andx has no idea anymore that it's
2048 * running from within a chain, so we have to fix up the
2049 * offset here.
2051 * Although it looks disgusting at this place, I want to keep
2052 * it here. The alternative would be to push knowledge about
2053 * the andx chain down into read&x again.
2056 if (smb_command == SMBreadX) {
2057 uint8_t *bytes_addr;
2059 if (wct < 7) {
2061 * Invalid read&x response
2063 return false;
2066 bytes_addr = outbuf + ofs /* vwv start */
2067 + sizeof(uint16_t) * wct /* vwv array */
2068 + sizeof(uint16_t); /* bcc */
2070 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2071 bytes_addr - outbuf - 4);
2074 ofs += sizeof(uint16_t) * wct;
2077 * bcc (byte count)
2080 SSVAL(outbuf, ofs, num_bytes);
2081 ofs += sizeof(uint16_t);
2084 * The bytes field
2087 memcpy(outbuf + ofs, bytes, num_bytes);
2089 return true;
2092 bool smb1_is_chain(const uint8_t *buf)
2094 uint8_t cmd, wct, andx_cmd;
2096 cmd = CVAL(buf, smb_com);
2097 if (!is_andx_req(cmd)) {
2098 return false;
2100 wct = CVAL(buf, smb_wct);
2101 if (wct < 2) {
2102 return false;
2104 andx_cmd = CVAL(buf, smb_vwv);
2105 return (andx_cmd != 0xFF);
2108 bool smb1_walk_chain(const uint8_t *buf,
2109 bool (*fn)(uint8_t cmd,
2110 uint8_t wct, const uint16_t *vwv,
2111 uint16_t num_bytes, const uint8_t *bytes,
2112 void *private_data),
2113 void *private_data)
2115 size_t smblen = smb_len(buf);
2116 const char *smb_buf = smb_base(buf);
2117 uint8_t cmd, chain_cmd;
2118 uint8_t wct;
2119 const uint16_t *vwv;
2120 uint16_t num_bytes;
2121 const uint8_t *bytes;
2123 cmd = CVAL(buf, smb_com);
2124 wct = CVAL(buf, smb_wct);
2125 vwv = (const uint16_t *)(buf + smb_vwv);
2126 num_bytes = smb_buflen(buf);
2127 bytes = (uint8_t *)smb_buf_const(buf);
2129 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2130 return false;
2133 if (!is_andx_req(cmd)) {
2134 return true;
2136 if (wct < 2) {
2137 return false;
2140 chain_cmd = CVAL(vwv, 0);
2142 while (chain_cmd != 0xff) {
2143 uint32_t chain_offset; /* uint32_t to avoid overflow */
2144 size_t length_needed;
2145 ptrdiff_t vwv_offset;
2147 chain_offset = SVAL(vwv+1, 0);
2150 * Check if the client tries to fool us. The chain
2151 * offset needs to point beyond the current request in
2152 * the chain, it needs to strictly grow. Otherwise we
2153 * might be tricked into an endless loop always
2154 * processing the same request over and over again. We
2155 * used to assume that vwv and the byte buffer array
2156 * in a chain are always attached, but OS/2 the
2157 * Write&X/Read&X chain puts the Read&X vwv array
2158 * right behind the Write&X vwv chain. The Write&X bcc
2159 * array is put behind the Read&X vwv array. So now we
2160 * check whether the chain offset points strictly
2161 * behind the previous vwv array. req->buf points
2162 * right after the vwv array of the previous
2163 * request. See
2164 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2165 * more information.
2168 vwv_offset = ((const char *)vwv - smb_buf);
2169 if (chain_offset <= vwv_offset) {
2170 return false;
2174 * Next check: Make sure the chain offset does not
2175 * point beyond the overall smb request length.
2178 length_needed = chain_offset+1; /* wct */
2179 if (length_needed > smblen) {
2180 return false;
2184 * Now comes the pointer magic. Goal here is to set up
2185 * vwv and buf correctly again. The chain offset (the
2186 * former vwv[1]) points at the new wct field.
2189 wct = CVAL(smb_buf, chain_offset);
2191 if (is_andx_req(chain_cmd) && (wct < 2)) {
2192 return false;
2196 * Next consistency check: Make the new vwv array fits
2197 * in the overall smb request.
2200 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2201 if (length_needed > smblen) {
2202 return false;
2204 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2207 * Now grab the new byte buffer....
2210 num_bytes = SVAL(vwv+wct, 0);
2213 * .. and check that it fits.
2216 length_needed += num_bytes;
2217 if (length_needed > smblen) {
2218 return false;
2220 bytes = (const uint8_t *)(vwv+wct+1);
2222 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2223 return false;
2226 if (!is_andx_req(chain_cmd)) {
2227 return true;
2229 chain_cmd = CVAL(vwv, 0);
2231 return true;
2234 static bool smb1_chain_length_cb(uint8_t cmd,
2235 uint8_t wct, const uint16_t *vwv,
2236 uint16_t num_bytes, const uint8_t *bytes,
2237 void *private_data)
2239 unsigned *count = (unsigned *)private_data;
2240 *count += 1;
2241 return true;
2244 unsigned smb1_chain_length(const uint8_t *buf)
2246 unsigned count = 0;
2248 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2249 return 0;
2251 return count;
2254 struct smb1_parse_chain_state {
2255 TALLOC_CTX *mem_ctx;
2256 const uint8_t *buf;
2257 struct smbd_server_connection *sconn;
2258 bool encrypted;
2259 uint32_t seqnum;
2261 struct smb_request **reqs;
2262 unsigned num_reqs;
2265 static bool smb1_parse_chain_cb(uint8_t cmd,
2266 uint8_t wct, const uint16_t *vwv,
2267 uint16_t num_bytes, const uint8_t *bytes,
2268 void *private_data)
2270 struct smb1_parse_chain_state *state =
2271 (struct smb1_parse_chain_state *)private_data;
2272 struct smb_request **reqs;
2273 struct smb_request *req;
2274 bool ok;
2276 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2277 struct smb_request *, state->num_reqs+1);
2278 if (reqs == NULL) {
2279 return false;
2281 state->reqs = reqs;
2283 req = talloc(reqs, struct smb_request);
2284 if (req == NULL) {
2285 return false;
2288 ok = init_smb_request(req, state->sconn, state->buf, 0,
2289 state->encrypted, state->seqnum);
2290 if (!ok) {
2291 return false;
2293 req->cmd = cmd;
2294 req->wct = wct;
2295 req->vwv = vwv;
2296 req->buflen = num_bytes;
2297 req->buf = bytes;
2299 reqs[state->num_reqs] = req;
2300 state->num_reqs += 1;
2301 return true;
2304 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2305 struct smbd_server_connection *sconn,
2306 bool encrypted, uint32_t seqnum,
2307 struct smb_request ***reqs, unsigned *num_reqs)
2309 struct smb1_parse_chain_state state;
2310 unsigned i;
2312 state.mem_ctx = mem_ctx;
2313 state.buf = buf;
2314 state.sconn = sconn;
2315 state.encrypted = encrypted;
2316 state.seqnum = seqnum;
2317 state.reqs = NULL;
2318 state.num_reqs = 0;
2320 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2321 TALLOC_FREE(state.reqs);
2322 return false;
2324 for (i=0; i<state.num_reqs; i++) {
2325 state.reqs[i]->chain = state.reqs;
2327 *reqs = state.reqs;
2328 *num_reqs = state.num_reqs;
2329 return true;
2332 /****************************************************************************
2333 Check if services need reloading.
2334 ****************************************************************************/
2336 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2339 if (last_smb_conf_reload_time == 0) {
2340 last_smb_conf_reload_time = t;
2343 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2344 reload_services(sconn, conn_snum_used, true);
2345 last_smb_conf_reload_time = t;
2349 static bool fd_is_readable(int fd)
2351 int ret, revents;
2353 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2355 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2359 static void smbd_server_connection_write_handler(
2360 struct smbd_server_connection *sconn)
2362 /* TODO: make write nonblocking */
2365 static void smbd_server_connection_read_handler(
2366 struct smbd_server_connection *sconn, int fd)
2368 uint8_t *inbuf = NULL;
2369 size_t inbuf_len = 0;
2370 size_t unread_bytes = 0;
2371 bool encrypted = false;
2372 TALLOC_CTX *mem_ctx = talloc_tos();
2373 NTSTATUS status;
2374 uint32_t seqnum;
2376 bool from_client;
2378 if (lp_async_smb_echo_handler()
2379 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2381 * This is the super-ugly hack to prefer the packets
2382 * forwarded by the echo handler over the ones by the
2383 * client directly
2385 fd = sconn->smb1.echo_handler.trusted_fd;
2388 from_client = (sconn->sock == fd);
2390 if (from_client) {
2391 smbd_lock_socket(sconn);
2393 if (!fd_is_readable(fd)) {
2394 DEBUG(10,("the echo listener was faster\n"));
2395 smbd_unlock_socket(sconn);
2396 return;
2400 /* TODO: make this completely nonblocking */
2401 status = receive_smb_talloc(mem_ctx, sconn, fd,
2402 (char **)(void *)&inbuf,
2403 0, /* timeout */
2404 &unread_bytes,
2405 &encrypted,
2406 &inbuf_len, &seqnum,
2407 false /* trusted channel */);
2409 if (from_client) {
2410 smbd_unlock_socket(sconn);
2413 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2414 goto process;
2416 if (NT_STATUS_IS_ERR(status)) {
2417 exit_server_cleanly("failed to receive smb request");
2419 if (!NT_STATUS_IS_OK(status)) {
2420 return;
2423 process:
2424 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2425 seqnum, encrypted, NULL);
2428 static void smbd_server_connection_handler(struct event_context *ev,
2429 struct fd_event *fde,
2430 uint16_t flags,
2431 void *private_data)
2433 struct smbd_server_connection *conn = talloc_get_type(private_data,
2434 struct smbd_server_connection);
2436 if (flags & EVENT_FD_WRITE) {
2437 smbd_server_connection_write_handler(conn);
2438 return;
2440 if (flags & EVENT_FD_READ) {
2441 smbd_server_connection_read_handler(conn, conn->sock);
2442 return;
2446 static void smbd_server_echo_handler(struct event_context *ev,
2447 struct fd_event *fde,
2448 uint16_t flags,
2449 void *private_data)
2451 struct smbd_server_connection *conn = talloc_get_type(private_data,
2452 struct smbd_server_connection);
2454 if (flags & EVENT_FD_WRITE) {
2455 smbd_server_connection_write_handler(conn);
2456 return;
2458 if (flags & EVENT_FD_READ) {
2459 smbd_server_connection_read_handler(
2460 conn, conn->smb1.echo_handler.trusted_fd);
2461 return;
2465 #ifdef CLUSTER_SUPPORT
2466 /****************************************************************************
2467 received when we should release a specific IP
2468 ****************************************************************************/
2469 static void release_ip(const char *ip, void *priv)
2471 const char *addr = (const char *)priv;
2472 const char *p = addr;
2474 if (strncmp("::ffff:", addr, 7) == 0) {
2475 p = addr + 7;
2478 DEBUG(10, ("Got release IP message for %s, "
2479 "our address is %s\n", ip, p));
2481 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2482 /* we can't afford to do a clean exit - that involves
2483 database writes, which would potentially mean we
2484 are still running after the failover has finished -
2485 we have to get rid of this process ID straight
2486 away */
2487 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2488 ip));
2489 /* note we must exit with non-zero status so the unclean handler gets
2490 called in the parent, so that the brl database is tickled */
2491 _exit(1);
2495 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2496 struct sockaddr_storage *client)
2498 socklen_t length;
2499 length = sizeof(*server);
2500 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2501 return -1;
2503 length = sizeof(*client);
2504 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2505 return -1;
2507 return 0;
2509 #endif
2512 * Send keepalive packets to our client
2514 static bool keepalive_fn(const struct timeval *now, void *private_data)
2516 struct smbd_server_connection *sconn = talloc_get_type_abort(
2517 private_data, struct smbd_server_connection);
2518 bool ret;
2520 if (sconn->using_smb2) {
2521 /* Don't do keepalives on an SMB2 connection. */
2522 return false;
2525 smbd_lock_socket(sconn);
2526 ret = send_keepalive(sconn->sock);
2527 smbd_unlock_socket(sconn);
2529 if (!ret) {
2530 char addr[INET6_ADDRSTRLEN];
2532 * Try and give an error message saying what
2533 * client failed.
2535 DEBUG(0, ("send_keepalive failed for client %s. "
2536 "Error %s - exiting\n",
2537 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2538 strerror(errno)));
2539 return False;
2541 return True;
2545 * Do the recurring check if we're idle
2547 static bool deadtime_fn(const struct timeval *now, void *private_data)
2549 struct smbd_server_connection *sconn =
2550 (struct smbd_server_connection *)private_data;
2552 if ((conn_num_open(sconn) == 0)
2553 || (conn_idle_all(sconn, now->tv_sec))) {
2554 DEBUG( 2, ( "Closing idle connection\n" ) );
2555 messaging_send(sconn->msg_ctx,
2556 messaging_server_id(sconn->msg_ctx),
2557 MSG_SHUTDOWN, &data_blob_null);
2558 return False;
2561 return True;
2565 * Do the recurring log file and smb.conf reload checks.
2568 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2570 struct smbd_server_connection *sconn = talloc_get_type_abort(
2571 private_data, struct smbd_server_connection);
2573 DEBUG(5, ("housekeeping\n"));
2575 change_to_root_user();
2577 /* update printer queue caches if necessary */
2578 update_monitored_printq_cache(sconn->msg_ctx);
2580 /* check if we need to reload services */
2581 check_reload(sconn, time_mono(NULL));
2583 /* Change machine password if neccessary. */
2584 attempt_machine_password_change();
2587 * Force a log file check.
2589 force_check_log_size();
2590 check_log_size();
2591 return true;
2595 * Read an smb packet in the echo handler child, giving the parent
2596 * smbd one second to react once the socket becomes readable.
2599 struct smbd_echo_read_state {
2600 struct tevent_context *ev;
2601 struct smbd_server_connection *sconn;
2603 char *buf;
2604 size_t buflen;
2605 uint32_t seqnum;
2608 static void smbd_echo_read_readable(struct tevent_req *subreq);
2609 static void smbd_echo_read_waited(struct tevent_req *subreq);
2611 static struct tevent_req *smbd_echo_read_send(
2612 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2613 struct smbd_server_connection *sconn)
2615 struct tevent_req *req, *subreq;
2616 struct smbd_echo_read_state *state;
2618 req = tevent_req_create(mem_ctx, &state,
2619 struct smbd_echo_read_state);
2620 if (req == NULL) {
2621 return NULL;
2623 state->ev = ev;
2624 state->sconn = sconn;
2626 subreq = wait_for_read_send(state, ev, sconn->sock);
2627 if (tevent_req_nomem(subreq, req)) {
2628 return tevent_req_post(req, ev);
2630 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2631 return req;
2634 static void smbd_echo_read_readable(struct tevent_req *subreq)
2636 struct tevent_req *req = tevent_req_callback_data(
2637 subreq, struct tevent_req);
2638 struct smbd_echo_read_state *state = tevent_req_data(
2639 req, struct smbd_echo_read_state);
2640 bool ok;
2641 int err;
2643 ok = wait_for_read_recv(subreq, &err);
2644 TALLOC_FREE(subreq);
2645 if (!ok) {
2646 tevent_req_nterror(req, map_nt_error_from_unix(err));
2647 return;
2651 * Give the parent smbd one second to step in
2654 subreq = tevent_wakeup_send(
2655 state, state->ev, timeval_current_ofs(1, 0));
2656 if (tevent_req_nomem(subreq, req)) {
2657 return;
2659 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2662 static void smbd_echo_read_waited(struct tevent_req *subreq)
2664 struct tevent_req *req = tevent_req_callback_data(
2665 subreq, struct tevent_req);
2666 struct smbd_echo_read_state *state = tevent_req_data(
2667 req, struct smbd_echo_read_state);
2668 struct smbd_server_connection *sconn = state->sconn;
2669 bool ok;
2670 NTSTATUS status;
2671 size_t unread = 0;
2672 bool encrypted;
2674 ok = tevent_wakeup_recv(subreq);
2675 TALLOC_FREE(subreq);
2676 if (!ok) {
2677 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2678 return;
2681 ok = smbd_lock_socket_internal(sconn);
2682 if (!ok) {
2683 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2684 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2685 return;
2688 if (!fd_is_readable(sconn->sock)) {
2689 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2690 (int)getpid()));
2692 ok = smbd_unlock_socket_internal(sconn);
2693 if (!ok) {
2694 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2695 DEBUG(1, ("%s: failed to unlock socket\n",
2696 __location__));
2697 return;
2700 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2701 if (tevent_req_nomem(subreq, req)) {
2702 return;
2704 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2705 return;
2708 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2709 0 /* timeout */,
2710 &unread,
2711 &encrypted,
2712 &state->buflen,
2713 &state->seqnum,
2714 false /* trusted_channel*/);
2716 if (tevent_req_nterror(req, status)) {
2717 tevent_req_nterror(req, status);
2718 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2719 (int)getpid(), nt_errstr(status)));
2720 return;
2723 ok = smbd_unlock_socket_internal(sconn);
2724 if (!ok) {
2725 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2726 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2727 return;
2729 tevent_req_done(req);
2732 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2733 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2735 struct smbd_echo_read_state *state = tevent_req_data(
2736 req, struct smbd_echo_read_state);
2737 NTSTATUS status;
2739 if (tevent_req_is_nterror(req, &status)) {
2740 return status;
2742 *pbuf = talloc_move(mem_ctx, &state->buf);
2743 *pbuflen = state->buflen;
2744 *pseqnum = state->seqnum;
2745 return NT_STATUS_OK;
2748 struct smbd_echo_state {
2749 struct tevent_context *ev;
2750 struct iovec *pending;
2751 struct smbd_server_connection *sconn;
2752 int parent_pipe;
2754 struct tevent_fd *parent_fde;
2756 struct tevent_req *write_req;
2759 static void smbd_echo_writer_done(struct tevent_req *req);
2761 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2763 int num_pending;
2765 if (state->write_req != NULL) {
2766 return;
2769 num_pending = talloc_array_length(state->pending);
2770 if (num_pending == 0) {
2771 return;
2774 state->write_req = writev_send(state, state->ev, NULL,
2775 state->parent_pipe, false,
2776 state->pending, num_pending);
2777 if (state->write_req == NULL) {
2778 DEBUG(1, ("writev_send failed\n"));
2779 exit(1);
2782 talloc_steal(state->write_req, state->pending);
2783 state->pending = NULL;
2785 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2786 state);
2789 static void smbd_echo_writer_done(struct tevent_req *req)
2791 struct smbd_echo_state *state = tevent_req_callback_data(
2792 req, struct smbd_echo_state);
2793 ssize_t written;
2794 int err;
2796 written = writev_recv(req, &err);
2797 TALLOC_FREE(req);
2798 state->write_req = NULL;
2799 if (written == -1) {
2800 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2801 exit(1);
2803 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2804 smbd_echo_activate_writer(state);
2807 static bool smbd_echo_reply(struct smbd_echo_state *state,
2808 uint8_t *inbuf, size_t inbuf_len,
2809 uint32_t seqnum)
2811 struct smb_request req;
2812 uint16_t num_replies;
2813 char *outbuf;
2814 bool ok;
2816 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2817 DEBUG(10, ("Got netbios keepalive\n"));
2819 * Just swallow it
2821 return true;
2824 if (inbuf_len < smb_size) {
2825 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2826 return false;
2828 if (!valid_smb_header(state->sconn, inbuf)) {
2829 DEBUG(10, ("Got invalid SMB header\n"));
2830 return false;
2833 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2834 seqnum)) {
2835 return false;
2837 req.inbuf = inbuf;
2839 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2840 smb_messages[req.cmd].name
2841 ? smb_messages[req.cmd].name : "unknown"));
2843 if (req.cmd != SMBecho) {
2844 return false;
2846 if (req.wct < 1) {
2847 return false;
2850 num_replies = SVAL(req.vwv+0, 0);
2851 if (num_replies != 1) {
2852 /* Not a Windows "Hey, you're still there?" request */
2853 return false;
2856 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2857 1, req.buflen)) {
2858 DEBUG(10, ("create_outbuf failed\n"));
2859 return false;
2861 req.outbuf = (uint8_t *)outbuf;
2863 SSVAL(req.outbuf, smb_vwv0, num_replies);
2865 if (req.buflen > 0) {
2866 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2869 ok = srv_send_smb(req.sconn,
2870 (char *)outbuf,
2871 true, seqnum+1,
2872 false, &req.pcd);
2873 TALLOC_FREE(outbuf);
2874 if (!ok) {
2875 exit(1);
2878 return true;
2881 static void smbd_echo_exit(struct tevent_context *ev,
2882 struct tevent_fd *fde, uint16_t flags,
2883 void *private_data)
2885 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2886 exit(0);
2889 static void smbd_echo_got_packet(struct tevent_req *req);
2891 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2892 int parent_pipe)
2894 struct smbd_echo_state *state;
2895 struct tevent_req *read_req;
2897 state = talloc_zero(sconn, struct smbd_echo_state);
2898 if (state == NULL) {
2899 DEBUG(1, ("talloc failed\n"));
2900 return;
2902 state->sconn = sconn;
2903 state->parent_pipe = parent_pipe;
2904 state->ev = s3_tevent_context_init(state);
2905 if (state->ev == NULL) {
2906 DEBUG(1, ("tevent_context_init failed\n"));
2907 TALLOC_FREE(state);
2908 return;
2910 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2911 TEVENT_FD_READ, smbd_echo_exit,
2912 state);
2913 if (state->parent_fde == NULL) {
2914 DEBUG(1, ("tevent_add_fd failed\n"));
2915 TALLOC_FREE(state);
2916 return;
2919 read_req = smbd_echo_read_send(state, state->ev, sconn);
2920 if (read_req == NULL) {
2921 DEBUG(1, ("smbd_echo_read_send failed\n"));
2922 TALLOC_FREE(state);
2923 return;
2925 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2927 while (true) {
2928 if (tevent_loop_once(state->ev) == -1) {
2929 DEBUG(1, ("tevent_loop_once failed: %s\n",
2930 strerror(errno)));
2931 break;
2934 TALLOC_FREE(state);
2937 static void smbd_echo_got_packet(struct tevent_req *req)
2939 struct smbd_echo_state *state = tevent_req_callback_data(
2940 req, struct smbd_echo_state);
2941 NTSTATUS status;
2942 char *buf = NULL;
2943 size_t buflen = 0;
2944 uint32_t seqnum = 0;
2945 bool reply;
2947 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2948 TALLOC_FREE(req);
2949 if (!NT_STATUS_IS_OK(status)) {
2950 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2951 nt_errstr(status)));
2952 exit(1);
2955 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2956 if (!reply) {
2957 size_t num_pending;
2958 struct iovec *tmp;
2959 struct iovec *iov;
2961 num_pending = talloc_array_length(state->pending);
2962 tmp = talloc_realloc(state, state->pending, struct iovec,
2963 num_pending+1);
2964 if (tmp == NULL) {
2965 DEBUG(1, ("talloc_realloc failed\n"));
2966 exit(1);
2968 state->pending = tmp;
2970 if (buflen >= smb_size) {
2972 * place the seqnum in the packet so that the main process
2973 * can reply with signing
2975 SIVAL(buf, smb_ss_field, seqnum);
2976 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2979 iov = &state->pending[num_pending];
2980 iov->iov_base = buf;
2981 iov->iov_len = buflen;
2983 DEBUG(10,("echo_handler[%d]: forward to main\n",
2984 (int)getpid()));
2985 smbd_echo_activate_writer(state);
2988 req = smbd_echo_read_send(state, state->ev, state->sconn);
2989 if (req == NULL) {
2990 DEBUG(1, ("smbd_echo_read_send failed\n"));
2991 exit(1);
2993 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2998 * Handle SMBecho requests in a forked child process
3000 bool fork_echo_handler(struct smbd_server_connection *sconn)
3002 int listener_pipe[2];
3003 int res;
3004 pid_t child;
3006 res = pipe(listener_pipe);
3007 if (res == -1) {
3008 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3009 return false;
3011 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3012 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3013 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3014 goto fail;
3017 child = fork();
3018 if (child == 0) {
3019 NTSTATUS status;
3021 close(listener_pipe[0]);
3022 set_blocking(listener_pipe[1], false);
3024 status = reinit_after_fork(sconn->msg_ctx,
3025 sconn->ev_ctx,
3026 false);
3027 if (!NT_STATUS_IS_OK(status)) {
3028 DEBUG(1, ("reinit_after_fork failed: %s\n",
3029 nt_errstr(status)));
3030 exit(1);
3032 smbd_echo_loop(sconn, listener_pipe[1]);
3033 exit(0);
3035 close(listener_pipe[1]);
3036 listener_pipe[1] = -1;
3037 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3039 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
3042 * Without smb signing this is the same as the normal smbd
3043 * listener. This needs to change once signing comes in.
3045 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3046 sconn,
3047 sconn->smb1.echo_handler.trusted_fd,
3048 TEVENT_FD_READ,
3049 smbd_server_echo_handler,
3050 sconn);
3051 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3052 DEBUG(1, ("event_add_fd failed\n"));
3053 goto fail;
3056 return true;
3058 fail:
3059 if (listener_pipe[0] != -1) {
3060 close(listener_pipe[0]);
3062 if (listener_pipe[1] != -1) {
3063 close(listener_pipe[1]);
3065 sconn->smb1.echo_handler.trusted_fd = -1;
3066 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3067 close(sconn->smb1.echo_handler.socket_lock_fd);
3069 sconn->smb1.echo_handler.trusted_fd = -1;
3070 sconn->smb1.echo_handler.socket_lock_fd = -1;
3071 return false;
3074 #if CLUSTER_SUPPORT
3076 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
3077 struct sockaddr_storage *srv,
3078 struct sockaddr_storage *clnt)
3080 struct ctdbd_connection *cconn;
3081 char tmp_addr[INET6_ADDRSTRLEN];
3082 char *addr;
3084 cconn = messaging_ctdbd_connection();
3085 if (cconn == NULL) {
3086 return NT_STATUS_NO_MEMORY;
3089 if (client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr)) == NULL) {
3090 return NT_STATUS_NO_MEMORY;
3092 addr = talloc_strdup(cconn, tmp_addr);
3093 if (addr == NULL) {
3094 return NT_STATUS_NO_MEMORY;
3096 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
3099 #endif
3101 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3103 while (user) {
3104 if (user->session_info &&
3105 (user->session_info->unix_token->uid == uid)) {
3106 return true;
3108 user = user->next;
3110 return false;
3113 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3115 while (user) {
3116 if (user->session_info != NULL) {
3117 int i;
3118 struct security_unix_token *utok;
3120 utok = user->session_info->unix_token;
3121 if (utok->gid == gid) {
3122 return true;
3124 for(i=0; i<utok->ngroups; i++) {
3125 if (utok->groups[i] == gid) {
3126 return true;
3130 user = user->next;
3132 return false;
3135 static bool sid_in_use(const struct user_struct *user,
3136 const struct dom_sid *psid)
3138 while (user) {
3139 struct security_token *tok;
3141 if (user->session_info == NULL) {
3142 continue;
3144 tok = user->session_info->security_token;
3145 if (tok == NULL) {
3147 * Not sure session_info->security_token can
3148 * ever be NULL. This check might be not
3149 * necessary.
3151 continue;
3153 if (security_token_has_sid(tok, psid)) {
3154 return true;
3156 user = user->next;
3158 return false;
3161 static bool id_in_use(const struct user_struct *user,
3162 const struct id_cache_ref *id)
3164 switch(id->type) {
3165 case UID:
3166 return uid_in_use(user, id->id.uid);
3167 case GID:
3168 return gid_in_use(user, id->id.gid);
3169 case SID:
3170 return sid_in_use(user, &id->id.sid);
3171 default:
3172 break;
3174 return false;
3177 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3178 void *private_data,
3179 uint32_t msg_type,
3180 struct server_id server_id,
3181 DATA_BLOB* data)
3183 const char *msg = (data && data->data)
3184 ? (const char *)data->data : "<NULL>";
3185 struct id_cache_ref id;
3186 struct smbd_server_connection *sconn =
3187 talloc_get_type_abort(private_data,
3188 struct smbd_server_connection);
3190 if (!id_cache_ref_parse(msg, &id)) {
3191 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3192 return;
3195 if (id_in_use(sconn->users, &id)) {
3196 exit_server_cleanly(msg);
3198 id_cache_delete_from_cache(&id);
3201 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3202 enum protocol_types protocol)
3204 NTSTATUS status;
3206 set_Protocol(protocol);
3207 conn->protocol = protocol;
3209 if (protocol >= PROTOCOL_SMB2_02) {
3210 status = smb2srv_session_table_init(conn);
3211 if (!NT_STATUS_IS_OK(status)) {
3212 return status;
3214 } else {
3215 status = smb1srv_session_table_init(conn);
3216 if (!NT_STATUS_IS_OK(status)) {
3217 return status;
3220 status = smb1srv_tcon_table_init(conn);
3221 if (!NT_STATUS_IS_OK(status)) {
3222 return status;
3226 return NT_STATUS_OK;
3229 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3230 void *private_data)
3232 struct smbXsrv_connection *conn =
3233 talloc_get_type_abort(private_data,
3234 struct smbXsrv_connection);
3236 switch (point) {
3237 case TEVENT_TRACE_BEFORE_WAIT:
3239 * This just removes compiler warning
3240 * without profile support
3242 conn->smbd_idle_profstamp = 0;
3243 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3244 break;
3245 case TEVENT_TRACE_AFTER_WAIT:
3246 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3247 break;
3251 /****************************************************************************
3252 Process commands from the client
3253 ****************************************************************************/
3255 void smbd_process(struct tevent_context *ev_ctx,
3256 struct messaging_context *msg_ctx,
3257 int sock_fd,
3258 bool interactive)
3260 TALLOC_CTX *frame = talloc_stackframe();
3261 struct smbXsrv_connection *conn;
3262 struct smbd_server_connection *sconn;
3263 struct sockaddr_storage ss;
3264 struct sockaddr *sa = NULL;
3265 socklen_t sa_socklen;
3266 struct tsocket_address *local_address = NULL;
3267 struct tsocket_address *remote_address = NULL;
3268 const char *locaddr = NULL;
3269 const char *remaddr = NULL;
3270 char *rhost;
3271 int ret;
3273 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3274 if (conn == NULL) {
3275 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3276 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3279 conn->ev_ctx = ev_ctx;
3280 conn->msg_ctx = msg_ctx;
3282 sconn = talloc_zero(conn, struct smbd_server_connection);
3283 if (!sconn) {
3284 exit_server("failed to create smbd_server_connection");
3287 conn->sconn = sconn;
3288 sconn->conn = conn;
3291 * TODO: remove this...:-)
3293 global_smbXsrv_connection = conn;
3295 sconn->ev_ctx = ev_ctx;
3296 sconn->msg_ctx = msg_ctx;
3297 sconn->sock = sock_fd;
3298 sconn->smb1.echo_handler.trusted_fd = -1;
3299 sconn->smb1.echo_handler.socket_lock_fd = -1;
3301 if (!interactive) {
3302 smbd_setup_sig_term_handler(sconn);
3303 smbd_setup_sig_hup_handler(sconn);
3305 if (!serverid_register(messaging_server_id(msg_ctx),
3306 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3307 |FLAG_MSG_DBWRAP
3308 |FLAG_MSG_PRINT_GENERAL)) {
3309 exit_server_cleanly("Could not register myself in "
3310 "serverid.tdb");
3314 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3316 * We're not making the decision here,
3317 * we're just allowing the client
3318 * to decide between SMB1 and SMB2
3319 * with the first negprot
3320 * packet.
3322 sconn->using_smb2 = true;
3325 /* Ensure child is set to blocking mode */
3326 set_blocking(sconn->sock,True);
3328 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3329 set_socket_options(sconn->sock, lp_socket_options());
3331 sa = (struct sockaddr *)(void *)&ss;
3332 sa_socklen = sizeof(ss);
3333 ret = getpeername(sconn->sock, sa, &sa_socklen);
3334 if (ret != 0) {
3335 int level = (errno == ENOTCONN)?2:0;
3336 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3337 exit_server_cleanly("getpeername() failed.\n");
3339 ret = tsocket_address_bsd_from_sockaddr(sconn,
3340 sa, sa_socklen,
3341 &remote_address);
3342 if (ret != 0) {
3343 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3344 __location__, strerror(errno)));
3345 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3348 sa = (struct sockaddr *)(void *)&ss;
3349 sa_socklen = sizeof(ss);
3350 ret = getsockname(sconn->sock, sa, &sa_socklen);
3351 if (ret != 0) {
3352 int level = (errno == ENOTCONN)?2:0;
3353 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3354 exit_server_cleanly("getsockname() failed.\n");
3356 ret = tsocket_address_bsd_from_sockaddr(sconn,
3357 sa, sa_socklen,
3358 &local_address);
3359 if (ret != 0) {
3360 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3361 __location__, strerror(errno)));
3362 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3365 sconn->local_address = local_address;
3366 sconn->remote_address = remote_address;
3368 if (tsocket_address_is_inet(local_address, "ip")) {
3369 locaddr = tsocket_address_inet_addr_string(
3370 sconn->local_address,
3371 talloc_tos());
3372 if (locaddr == NULL) {
3373 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3374 __location__, strerror(errno)));
3375 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3377 } else {
3378 locaddr = "0.0.0.0";
3381 if (tsocket_address_is_inet(remote_address, "ip")) {
3382 remaddr = tsocket_address_inet_addr_string(
3383 sconn->remote_address,
3384 talloc_tos());
3385 if (remaddr == NULL) {
3386 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3387 __location__, strerror(errno)));
3388 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3390 } else {
3391 remaddr = "0.0.0.0";
3394 /* this is needed so that we get decent entries
3395 in smbstatus for port 445 connects */
3396 set_remote_machine_name(remaddr, false);
3397 reload_services(sconn, conn_snum_used, true);
3400 * Before the first packet, check the global hosts allow/ hosts deny
3401 * parameters before doing any parsing of packets passed to us by the
3402 * client. This prevents attacks on our parsing code from hosts not in
3403 * the hosts allow list.
3406 ret = get_remote_hostname(remote_address,
3407 &rhost,
3408 talloc_tos());
3409 if (ret < 0) {
3410 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3411 __location__, strerror(errno)));
3412 exit_server_cleanly("get_remote_hostname failed.\n");
3414 if (strequal(rhost, "UNKNOWN")) {
3415 rhost = talloc_strdup(talloc_tos(), remaddr);
3417 sconn->remote_hostname = talloc_move(sconn, &rhost);
3419 sub_set_socket_ids(remaddr,
3420 sconn->remote_hostname,
3421 locaddr);
3423 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3424 sconn->remote_hostname,
3425 remaddr)) {
3427 * send a negative session response "not listening on calling
3428 * name"
3430 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3431 DEBUG( 1, ("Connection denied from %s to %s\n",
3432 tsocket_address_string(remote_address, talloc_tos()),
3433 tsocket_address_string(local_address, talloc_tos())));
3434 (void)srv_send_smb(sconn,(char *)buf, false,
3435 0, false, NULL);
3436 exit_server_cleanly("connection denied");
3439 DEBUG(10, ("Connection allowed from %s to %s\n",
3440 tsocket_address_string(remote_address, talloc_tos()),
3441 tsocket_address_string(local_address, talloc_tos())));
3443 if (lp_preload_modules()) {
3444 smb_load_modules(lp_preload_modules());
3447 smb_perfcount_init();
3449 if (!init_account_policy()) {
3450 exit_server("Could not open account policy tdb.\n");
3453 if (*lp_rootdir()) {
3454 if (chroot(lp_rootdir()) != 0) {
3455 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3456 exit_server("Failed to chroot()");
3458 if (chdir("/") == -1) {
3459 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3460 exit_server("Failed to chroot()");
3462 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3465 if (!srv_init_signing(sconn)) {
3466 exit_server("Failed to init smb_signing");
3469 if (!file_init(sconn)) {
3470 exit_server("file_init() failed");
3473 /* Setup oplocks */
3474 if (!init_oplocks(sconn))
3475 exit_server("Failed to init oplocks");
3477 /* register our message handlers */
3478 messaging_register(sconn->msg_ctx, sconn,
3479 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3480 messaging_register(sconn->msg_ctx, sconn,
3481 MSG_SMB_CLOSE_FILE, msg_close_file);
3482 messaging_register(sconn->msg_ctx, sconn,
3483 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3485 id_cache_register_msgs(sconn->msg_ctx);
3486 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3487 messaging_register(sconn->msg_ctx, sconn,
3488 ID_CACHE_KILL, smbd_id_cache_kill);
3490 messaging_deregister(sconn->msg_ctx,
3491 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3492 messaging_register(sconn->msg_ctx, sconn,
3493 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3496 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3497 * MSGs to all child processes
3499 messaging_deregister(sconn->msg_ctx,
3500 MSG_DEBUG, NULL);
3501 messaging_register(sconn->msg_ctx, NULL,
3502 MSG_DEBUG, debug_message);
3504 if ((lp_keepalive() != 0)
3505 && !(event_add_idle(ev_ctx, NULL,
3506 timeval_set(lp_keepalive(), 0),
3507 "keepalive", keepalive_fn,
3508 sconn))) {
3509 DEBUG(0, ("Could not add keepalive event\n"));
3510 exit(1);
3513 if (!(event_add_idle(ev_ctx, NULL,
3514 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3515 "deadtime", deadtime_fn, sconn))) {
3516 DEBUG(0, ("Could not add deadtime event\n"));
3517 exit(1);
3520 if (!(event_add_idle(ev_ctx, NULL,
3521 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3522 "housekeeping", housekeeping_fn, sconn))) {
3523 DEBUG(0, ("Could not add housekeeping event\n"));
3524 exit(1);
3527 #ifdef CLUSTER_SUPPORT
3529 if (lp_clustering()) {
3531 * We need to tell ctdb about our client's TCP
3532 * connection, so that for failover ctdbd can send
3533 * tickle acks, triggering a reconnection by the
3534 * client.
3537 struct sockaddr_storage srv, clnt;
3539 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3540 NTSTATUS status;
3541 status = smbd_register_ips(sconn, &srv, &clnt);
3542 if (!NT_STATUS_IS_OK(status)) {
3543 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3544 nt_errstr(status)));
3546 } else
3548 DEBUG(0,("Unable to get tcp info for "
3549 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3550 strerror(errno)));
3554 #endif
3556 sconn->nbt.got_session = false;
3558 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3560 sconn->smb1.sessions.done_sesssetup = false;
3561 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3562 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3564 if (!init_dptrs(sconn)) {
3565 exit_server("init_dptrs() failed");
3568 sconn->smb1.fde = event_add_fd(ev_ctx,
3569 sconn,
3570 sconn->sock,
3571 EVENT_FD_READ,
3572 smbd_server_connection_handler,
3573 sconn);
3574 if (!sconn->smb1.fde) {
3575 exit_server("failed to create smbd_server_connection fde");
3578 sconn->conn->local_address = sconn->local_address;
3579 sconn->conn->remote_address = sconn->remote_address;
3580 sconn->conn->remote_hostname = sconn->remote_hostname;
3581 sconn->conn->protocol = PROTOCOL_NONE;
3583 TALLOC_FREE(frame);
3585 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3587 while (True) {
3588 frame = talloc_stackframe_pool(8192);
3590 errno = 0;
3591 if (tevent_loop_once(ev_ctx) == -1) {
3592 if (errno != EINTR) {
3593 DEBUG(3, ("tevent_loop_once failed: %s,"
3594 " exiting\n", strerror(errno) ));
3595 break;
3599 TALLOC_FREE(frame);
3602 exit_server_cleanly(NULL);
3605 bool req_is_in_chain(struct smb_request *req)
3607 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3609 * We're right now handling a subsequent request, so we must
3610 * be in a chain
3612 return true;
3615 if (!is_andx_req(req->cmd)) {
3616 return false;
3619 if (req->wct < 2) {
3621 * Okay, an illegal request, but definitely not chained :-)
3623 return false;
3626 return (CVAL(req->vwv+0, 0) != 0xFF);