Use new common function.
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blobf8757faae0d0983c63e3d4927ddad62aa765da22
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 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
722 uint64_t mid)
724 struct pending_message_list *pml;
725 int i = 0;
727 if (sconn->using_smb2) {
728 return schedule_deferred_open_message_smb2(sconn, mid);
731 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
732 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
734 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
735 "msg_mid = %llu\n",
736 i++,
737 (unsigned long long)msg_mid ));
739 if (mid == msg_mid) {
740 struct timed_event *te;
742 if (pml->processed) {
743 /* A processed message should not be
744 * rescheduled. */
745 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
746 "message mid %llu was already processed\n",
747 (unsigned long long)msg_mid ));
748 continue;
751 DEBUG(10,("schedule_deferred_open_message_smb: "
752 "scheduling mid %llu\n",
753 (unsigned long long)mid ));
755 te = tevent_add_timer(pml->sconn->ev_ctx,
756 pml,
757 timeval_zero(),
758 smbd_deferred_open_timer,
759 pml);
760 if (!te) {
761 DEBUG(10,("schedule_deferred_open_message_smb: "
762 "event_add_timed() failed, "
763 "skipping mid %llu\n",
764 (unsigned long long)msg_mid ));
767 TALLOC_FREE(pml->te);
768 pml->te = te;
769 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
770 return true;
774 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
775 "find message mid %llu\n",
776 (unsigned long long)mid ));
778 return false;
781 /****************************************************************************
782 Return true if this mid is on the deferred queue and was not yet processed.
783 ****************************************************************************/
785 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
787 struct pending_message_list *pml;
789 if (sconn->using_smb2) {
790 return open_was_deferred_smb2(sconn, mid);
793 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
794 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
795 return True;
798 return False;
801 /****************************************************************************
802 Return the message queued by this mid.
803 ****************************************************************************/
805 static struct pending_message_list *get_deferred_open_message_smb(
806 struct smbd_server_connection *sconn, uint64_t mid)
808 struct pending_message_list *pml;
810 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
811 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
812 return pml;
815 return NULL;
818 /****************************************************************************
819 Get the state data queued by this mid.
820 ****************************************************************************/
822 bool get_deferred_open_message_state(struct smb_request *smbreq,
823 struct timeval *p_request_time,
824 void **pp_state)
826 struct pending_message_list *pml;
828 if (smbreq->sconn->using_smb2) {
829 return get_deferred_open_message_state_smb2(smbreq->smb2req,
830 p_request_time,
831 pp_state);
834 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
835 if (!pml) {
836 return false;
838 if (p_request_time) {
839 *p_request_time = pml->request_time;
841 if (pp_state) {
842 *pp_state = (void *)pml->private_data.data;
844 return true;
847 /****************************************************************************
848 Function to push a deferred open smb message onto a linked list of local smb
849 messages ready for processing.
850 ****************************************************************************/
852 bool push_deferred_open_message_smb(struct smb_request *req,
853 struct timeval request_time,
854 struct timeval timeout,
855 struct file_id id,
856 char *private_data, size_t priv_len)
858 struct timeval end_time;
860 if (req->smb2req) {
861 return push_deferred_open_message_smb2(req->smb2req,
862 request_time,
863 timeout,
865 private_data,
866 priv_len);
869 if (req->unread_bytes) {
870 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
871 "unread_bytes = %u\n",
872 (unsigned int)req->unread_bytes ));
873 smb_panic("push_deferred_open_message_smb: "
874 "logic error unread_bytes != 0" );
877 end_time = timeval_sum(&request_time, &timeout);
879 DEBUG(10,("push_deferred_open_message_smb: pushing message "
880 "len %u mid %llu timeout time [%u.%06u]\n",
881 (unsigned int) smb_len(req->inbuf)+4,
882 (unsigned long long)req->mid,
883 (unsigned int)end_time.tv_sec,
884 (unsigned int)end_time.tv_usec));
886 return push_queued_message(req, request_time, end_time,
887 private_data, priv_len);
890 static void smbd_sig_term_handler(struct tevent_context *ev,
891 struct tevent_signal *se,
892 int signum,
893 int count,
894 void *siginfo,
895 void *private_data)
897 exit_server_cleanly("termination signal");
900 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
902 struct tevent_signal *se;
904 se = tevent_add_signal(sconn->ev_ctx,
905 sconn,
906 SIGTERM, 0,
907 smbd_sig_term_handler,
908 sconn);
909 if (!se) {
910 exit_server("failed to setup SIGTERM handler");
914 static void smbd_sig_hup_handler(struct tevent_context *ev,
915 struct tevent_signal *se,
916 int signum,
917 int count,
918 void *siginfo,
919 void *private_data)
921 struct smbd_server_connection *sconn =
922 talloc_get_type_abort(private_data,
923 struct smbd_server_connection);
925 change_to_root_user();
926 DEBUG(1,("Reloading services after SIGHUP\n"));
927 reload_services(sconn, conn_snum_used, false);
930 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
932 struct tevent_signal *se;
934 se = tevent_add_signal(sconn->ev_ctx,
935 sconn,
936 SIGHUP, 0,
937 smbd_sig_hup_handler,
938 sconn);
939 if (!se) {
940 exit_server("failed to setup SIGHUP handler");
944 static void smbd_conf_updated(struct messaging_context *msg,
945 void *private_data,
946 uint32_t msg_type,
947 struct server_id server_id,
948 DATA_BLOB *data)
950 struct smbd_server_connection *sconn =
951 talloc_get_type_abort(private_data,
952 struct smbd_server_connection);
954 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
955 "updated. Reloading.\n"));
956 change_to_root_user();
957 reload_services(sconn, conn_snum_used, false);
961 * Only allow 5 outstanding trans requests. We're allocating memory, so
962 * prevent a DoS.
965 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
967 int count = 0;
968 for (; list != NULL; list = list->next) {
970 if (list->mid == mid) {
971 return NT_STATUS_INVALID_PARAMETER;
974 count += 1;
976 if (count > 5) {
977 return NT_STATUS_INSUFFICIENT_RESOURCES;
980 return NT_STATUS_OK;
984 These flags determine some of the permissions required to do an operation
986 Note that I don't set NEED_WRITE on some write operations because they
987 are used by some brain-dead clients when printing, and I don't want to
988 force write permissions on print services.
990 #define AS_USER (1<<0)
991 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
992 #define TIME_INIT (1<<2)
993 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
994 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
995 #define DO_CHDIR (1<<6)
998 define a list of possible SMB messages and their corresponding
999 functions. Any message that has a NULL function is unimplemented -
1000 please feel free to contribute implementations!
1002 static const struct smb_message_struct {
1003 const char *name;
1004 void (*fn)(struct smb_request *req);
1005 int flags;
1006 } smb_messages[256] = {
1008 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1009 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1010 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1011 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1012 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1013 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1014 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1015 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1016 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1017 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1018 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1019 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1020 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1021 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1022 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1023 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1024 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1025 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1026 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1027 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1028 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1029 /* 0x15 */ { NULL, NULL, 0 },
1030 /* 0x16 */ { NULL, NULL, 0 },
1031 /* 0x17 */ { NULL, NULL, 0 },
1032 /* 0x18 */ { NULL, NULL, 0 },
1033 /* 0x19 */ { NULL, NULL, 0 },
1034 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1035 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1036 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1037 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1038 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1039 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1040 /* 0x20 */ { "SMBwritec", NULL,0},
1041 /* 0x21 */ { NULL, NULL, 0 },
1042 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1043 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1044 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1045 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1046 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1047 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1048 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1049 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1050 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1051 /* 0x2b */ { "SMBecho",reply_echo,0},
1052 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1053 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1054 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1055 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1056 /* 0x30 */ { NULL, NULL, 0 },
1057 /* 0x31 */ { NULL, NULL, 0 },
1058 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1059 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1060 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1061 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1062 /* 0x36 */ { NULL, NULL, 0 },
1063 /* 0x37 */ { NULL, NULL, 0 },
1064 /* 0x38 */ { NULL, NULL, 0 },
1065 /* 0x39 */ { NULL, NULL, 0 },
1066 /* 0x3a */ { NULL, NULL, 0 },
1067 /* 0x3b */ { NULL, NULL, 0 },
1068 /* 0x3c */ { NULL, NULL, 0 },
1069 /* 0x3d */ { NULL, NULL, 0 },
1070 /* 0x3e */ { NULL, NULL, 0 },
1071 /* 0x3f */ { NULL, NULL, 0 },
1072 /* 0x40 */ { NULL, NULL, 0 },
1073 /* 0x41 */ { NULL, NULL, 0 },
1074 /* 0x42 */ { NULL, NULL, 0 },
1075 /* 0x43 */ { NULL, NULL, 0 },
1076 /* 0x44 */ { NULL, NULL, 0 },
1077 /* 0x45 */ { NULL, NULL, 0 },
1078 /* 0x46 */ { NULL, NULL, 0 },
1079 /* 0x47 */ { NULL, NULL, 0 },
1080 /* 0x48 */ { NULL, NULL, 0 },
1081 /* 0x49 */ { NULL, NULL, 0 },
1082 /* 0x4a */ { NULL, NULL, 0 },
1083 /* 0x4b */ { NULL, NULL, 0 },
1084 /* 0x4c */ { NULL, NULL, 0 },
1085 /* 0x4d */ { NULL, NULL, 0 },
1086 /* 0x4e */ { NULL, NULL, 0 },
1087 /* 0x4f */ { NULL, NULL, 0 },
1088 /* 0x50 */ { NULL, NULL, 0 },
1089 /* 0x51 */ { NULL, NULL, 0 },
1090 /* 0x52 */ { NULL, NULL, 0 },
1091 /* 0x53 */ { NULL, NULL, 0 },
1092 /* 0x54 */ { NULL, NULL, 0 },
1093 /* 0x55 */ { NULL, NULL, 0 },
1094 /* 0x56 */ { NULL, NULL, 0 },
1095 /* 0x57 */ { NULL, NULL, 0 },
1096 /* 0x58 */ { NULL, NULL, 0 },
1097 /* 0x59 */ { NULL, NULL, 0 },
1098 /* 0x5a */ { NULL, NULL, 0 },
1099 /* 0x5b */ { NULL, NULL, 0 },
1100 /* 0x5c */ { NULL, NULL, 0 },
1101 /* 0x5d */ { NULL, NULL, 0 },
1102 /* 0x5e */ { NULL, NULL, 0 },
1103 /* 0x5f */ { NULL, NULL, 0 },
1104 /* 0x60 */ { NULL, NULL, 0 },
1105 /* 0x61 */ { NULL, NULL, 0 },
1106 /* 0x62 */ { NULL, NULL, 0 },
1107 /* 0x63 */ { NULL, NULL, 0 },
1108 /* 0x64 */ { NULL, NULL, 0 },
1109 /* 0x65 */ { NULL, NULL, 0 },
1110 /* 0x66 */ { NULL, NULL, 0 },
1111 /* 0x67 */ { NULL, NULL, 0 },
1112 /* 0x68 */ { NULL, NULL, 0 },
1113 /* 0x69 */ { NULL, NULL, 0 },
1114 /* 0x6a */ { NULL, NULL, 0 },
1115 /* 0x6b */ { NULL, NULL, 0 },
1116 /* 0x6c */ { NULL, NULL, 0 },
1117 /* 0x6d */ { NULL, NULL, 0 },
1118 /* 0x6e */ { NULL, NULL, 0 },
1119 /* 0x6f */ { NULL, NULL, 0 },
1120 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1121 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1122 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1123 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1124 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1125 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1126 /* 0x76 */ { NULL, NULL, 0 },
1127 /* 0x77 */ { NULL, NULL, 0 },
1128 /* 0x78 */ { NULL, NULL, 0 },
1129 /* 0x79 */ { NULL, NULL, 0 },
1130 /* 0x7a */ { NULL, NULL, 0 },
1131 /* 0x7b */ { NULL, NULL, 0 },
1132 /* 0x7c */ { NULL, NULL, 0 },
1133 /* 0x7d */ { NULL, NULL, 0 },
1134 /* 0x7e */ { NULL, NULL, 0 },
1135 /* 0x7f */ { NULL, NULL, 0 },
1136 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1137 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1138 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1139 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1140 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1141 /* 0x85 */ { NULL, NULL, 0 },
1142 /* 0x86 */ { NULL, NULL, 0 },
1143 /* 0x87 */ { NULL, NULL, 0 },
1144 /* 0x88 */ { NULL, NULL, 0 },
1145 /* 0x89 */ { NULL, NULL, 0 },
1146 /* 0x8a */ { NULL, NULL, 0 },
1147 /* 0x8b */ { NULL, NULL, 0 },
1148 /* 0x8c */ { NULL, NULL, 0 },
1149 /* 0x8d */ { NULL, NULL, 0 },
1150 /* 0x8e */ { NULL, NULL, 0 },
1151 /* 0x8f */ { NULL, NULL, 0 },
1152 /* 0x90 */ { NULL, NULL, 0 },
1153 /* 0x91 */ { NULL, NULL, 0 },
1154 /* 0x92 */ { NULL, NULL, 0 },
1155 /* 0x93 */ { NULL, NULL, 0 },
1156 /* 0x94 */ { NULL, NULL, 0 },
1157 /* 0x95 */ { NULL, NULL, 0 },
1158 /* 0x96 */ { NULL, NULL, 0 },
1159 /* 0x97 */ { NULL, NULL, 0 },
1160 /* 0x98 */ { NULL, NULL, 0 },
1161 /* 0x99 */ { NULL, NULL, 0 },
1162 /* 0x9a */ { NULL, NULL, 0 },
1163 /* 0x9b */ { NULL, NULL, 0 },
1164 /* 0x9c */ { NULL, NULL, 0 },
1165 /* 0x9d */ { NULL, NULL, 0 },
1166 /* 0x9e */ { NULL, NULL, 0 },
1167 /* 0x9f */ { NULL, NULL, 0 },
1168 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1169 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1170 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1171 /* 0xa3 */ { NULL, NULL, 0 },
1172 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1173 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1174 /* 0xa6 */ { NULL, NULL, 0 },
1175 /* 0xa7 */ { NULL, NULL, 0 },
1176 /* 0xa8 */ { NULL, NULL, 0 },
1177 /* 0xa9 */ { NULL, NULL, 0 },
1178 /* 0xaa */ { NULL, NULL, 0 },
1179 /* 0xab */ { NULL, NULL, 0 },
1180 /* 0xac */ { NULL, NULL, 0 },
1181 /* 0xad */ { NULL, NULL, 0 },
1182 /* 0xae */ { NULL, NULL, 0 },
1183 /* 0xaf */ { NULL, NULL, 0 },
1184 /* 0xb0 */ { NULL, NULL, 0 },
1185 /* 0xb1 */ { NULL, NULL, 0 },
1186 /* 0xb2 */ { NULL, NULL, 0 },
1187 /* 0xb3 */ { NULL, NULL, 0 },
1188 /* 0xb4 */ { NULL, NULL, 0 },
1189 /* 0xb5 */ { NULL, NULL, 0 },
1190 /* 0xb6 */ { NULL, NULL, 0 },
1191 /* 0xb7 */ { NULL, NULL, 0 },
1192 /* 0xb8 */ { NULL, NULL, 0 },
1193 /* 0xb9 */ { NULL, NULL, 0 },
1194 /* 0xba */ { NULL, NULL, 0 },
1195 /* 0xbb */ { NULL, NULL, 0 },
1196 /* 0xbc */ { NULL, NULL, 0 },
1197 /* 0xbd */ { NULL, NULL, 0 },
1198 /* 0xbe */ { NULL, NULL, 0 },
1199 /* 0xbf */ { NULL, NULL, 0 },
1200 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1201 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1202 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1203 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1204 /* 0xc4 */ { NULL, NULL, 0 },
1205 /* 0xc5 */ { NULL, NULL, 0 },
1206 /* 0xc6 */ { NULL, NULL, 0 },
1207 /* 0xc7 */ { NULL, NULL, 0 },
1208 /* 0xc8 */ { NULL, NULL, 0 },
1209 /* 0xc9 */ { NULL, NULL, 0 },
1210 /* 0xca */ { NULL, NULL, 0 },
1211 /* 0xcb */ { NULL, NULL, 0 },
1212 /* 0xcc */ { NULL, NULL, 0 },
1213 /* 0xcd */ { NULL, NULL, 0 },
1214 /* 0xce */ { NULL, NULL, 0 },
1215 /* 0xcf */ { NULL, NULL, 0 },
1216 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1217 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1218 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1219 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1220 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1221 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1222 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1223 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1224 /* 0xd8 */ { NULL, NULL, 0 },
1225 /* 0xd9 */ { NULL, NULL, 0 },
1226 /* 0xda */ { NULL, NULL, 0 },
1227 /* 0xdb */ { NULL, NULL, 0 },
1228 /* 0xdc */ { NULL, NULL, 0 },
1229 /* 0xdd */ { NULL, NULL, 0 },
1230 /* 0xde */ { NULL, NULL, 0 },
1231 /* 0xdf */ { NULL, NULL, 0 },
1232 /* 0xe0 */ { NULL, NULL, 0 },
1233 /* 0xe1 */ { NULL, NULL, 0 },
1234 /* 0xe2 */ { NULL, NULL, 0 },
1235 /* 0xe3 */ { NULL, NULL, 0 },
1236 /* 0xe4 */ { NULL, NULL, 0 },
1237 /* 0xe5 */ { NULL, NULL, 0 },
1238 /* 0xe6 */ { NULL, NULL, 0 },
1239 /* 0xe7 */ { NULL, NULL, 0 },
1240 /* 0xe8 */ { NULL, NULL, 0 },
1241 /* 0xe9 */ { NULL, NULL, 0 },
1242 /* 0xea */ { NULL, NULL, 0 },
1243 /* 0xeb */ { NULL, NULL, 0 },
1244 /* 0xec */ { NULL, NULL, 0 },
1245 /* 0xed */ { NULL, NULL, 0 },
1246 /* 0xee */ { NULL, NULL, 0 },
1247 /* 0xef */ { NULL, NULL, 0 },
1248 /* 0xf0 */ { NULL, NULL, 0 },
1249 /* 0xf1 */ { NULL, NULL, 0 },
1250 /* 0xf2 */ { NULL, NULL, 0 },
1251 /* 0xf3 */ { NULL, NULL, 0 },
1252 /* 0xf4 */ { NULL, NULL, 0 },
1253 /* 0xf5 */ { NULL, NULL, 0 },
1254 /* 0xf6 */ { NULL, NULL, 0 },
1255 /* 0xf7 */ { NULL, NULL, 0 },
1256 /* 0xf8 */ { NULL, NULL, 0 },
1257 /* 0xf9 */ { NULL, NULL, 0 },
1258 /* 0xfa */ { NULL, NULL, 0 },
1259 /* 0xfb */ { NULL, NULL, 0 },
1260 /* 0xfc */ { NULL, NULL, 0 },
1261 /* 0xfd */ { NULL, NULL, 0 },
1262 /* 0xfe */ { NULL, NULL, 0 },
1263 /* 0xff */ { NULL, NULL, 0 }
1267 /*******************************************************************
1268 allocate and initialize a reply packet
1269 ********************************************************************/
1271 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1272 const char *inbuf, char **outbuf, uint8_t num_words,
1273 uint32_t num_bytes)
1276 * Protect against integer wrap
1278 if ((num_bytes > 0xffffff)
1279 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1280 char *msg;
1281 if (asprintf(&msg, "num_bytes too large: %u",
1282 (unsigned)num_bytes) == -1) {
1283 msg = discard_const_p(char, "num_bytes too large");
1285 smb_panic(msg);
1288 *outbuf = talloc_array(mem_ctx, char,
1289 smb_size + num_words*2 + num_bytes);
1290 if (*outbuf == NULL) {
1291 return false;
1294 construct_reply_common(req, inbuf, *outbuf);
1295 srv_set_message(*outbuf, num_words, num_bytes, false);
1297 * Zero out the word area, the caller has to take care of the bcc area
1298 * himself
1300 if (num_words != 0) {
1301 memset(*outbuf + smb_vwv0, 0, num_words*2);
1304 return true;
1307 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1309 char *outbuf;
1310 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1311 num_bytes)) {
1312 smb_panic("could not allocate output buffer\n");
1314 req->outbuf = (uint8_t *)outbuf;
1318 /*******************************************************************
1319 Dump a packet to a file.
1320 ********************************************************************/
1322 static void smb_dump(const char *name, int type, const char *data)
1324 size_t len;
1325 int fd, i;
1326 char *fname = NULL;
1327 if (DEBUGLEVEL < 50) {
1328 return;
1331 len = smb_len_tcp(data)+4;
1332 for (i=1;i<100;i++) {
1333 fname = talloc_asprintf(talloc_tos(),
1334 "/tmp/%s.%d.%s",
1335 name,
1337 type ? "req" : "resp");
1338 if (fname == NULL) {
1339 return;
1341 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1342 if (fd != -1 || errno != EEXIST) break;
1343 TALLOC_FREE(fname);
1345 if (fd != -1) {
1346 ssize_t ret = write(fd, data, len);
1347 if (ret != len)
1348 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1349 close(fd);
1350 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1352 TALLOC_FREE(fname);
1355 /****************************************************************************
1356 Prepare everything for calling the actual request function, and potentially
1357 call the request function via the "new" interface.
1359 Return False if the "legacy" function needs to be called, everything is
1360 prepared.
1362 Return True if we're done.
1364 I know this API sucks, but it is the one with the least code change I could
1365 find.
1366 ****************************************************************************/
1368 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1370 int flags;
1371 uint64_t session_tag;
1372 connection_struct *conn = NULL;
1373 struct smbd_server_connection *sconn = req->sconn;
1374 NTTIME now = timeval_to_nttime(&req->request_time);
1375 struct smbXsrv_session *session = NULL;
1376 NTSTATUS status;
1378 errno = 0;
1380 if (smb_messages[type].fn == NULL) {
1381 DEBUG(0,("Unknown message type %d!\n",type));
1382 smb_dump("Unknown", 1, (const char *)req->inbuf);
1383 reply_unknown_new(req, type);
1384 return NULL;
1387 flags = smb_messages[type].flags;
1389 /* In share mode security we must ignore the vuid. */
1390 session_tag = req->vuid;
1391 conn = req->conn;
1393 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1394 (int)getpid(), (unsigned long)conn));
1396 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1398 /* Ensure this value is replaced in the incoming packet. */
1399 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1402 * Ensure the correct username is in current_user_info. This is a
1403 * really ugly bugfix for problems with multiple session_setup_and_X's
1404 * being done and allowing %U and %G substitutions to work correctly.
1405 * There is a reason this code is done here, don't move it unless you
1406 * know what you're doing... :-).
1407 * JRA.
1411 * lookup an existing session
1413 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1414 * here, the main check is still in change_to_user()
1416 status = smb1srv_session_lookup(sconn->conn,
1417 session_tag,
1418 now,
1419 &session);
1420 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1421 switch (type) {
1422 case SMBsesssetupX:
1423 status = NT_STATUS_OK;
1424 break;
1425 default:
1426 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1427 (unsigned long long)session_tag,
1428 (unsigned long long)req->mid));
1429 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1430 return conn;
1434 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1435 struct user_struct *vuser = NULL;
1437 sconn->smb1.sessions.last_session_tag = session_tag;
1438 if (session) {
1439 vuser = session->compat;
1441 if (vuser) {
1442 set_current_user_info(
1443 vuser->session_info->unix_info->sanitized_username,
1444 vuser->session_info->unix_info->unix_name,
1445 vuser->session_info->info->domain_name);
1449 /* Does this call need to be run as the connected user? */
1450 if (flags & AS_USER) {
1452 /* Does this call need a valid tree connection? */
1453 if (!conn) {
1455 * Amazingly, the error code depends on the command
1456 * (from Samba4).
1458 if (type == SMBntcreateX) {
1459 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1460 } else {
1461 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1463 return NULL;
1466 if (!change_to_user(conn,session_tag)) {
1467 DEBUG(0, ("Error: Could not change to user. Removing "
1468 "deferred open, mid=%llu.\n",
1469 (unsigned long long)req->mid));
1470 reply_force_doserror(req, ERRSRV, ERRbaduid);
1471 return conn;
1474 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1476 /* Does it need write permission? */
1477 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1478 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1479 return conn;
1482 /* IPC services are limited */
1483 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1484 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1485 return conn;
1487 } else {
1488 /* This call needs to be run as root */
1489 change_to_root_user();
1492 /* load service specific parameters */
1493 if (conn) {
1494 if (req->encrypted) {
1495 conn->encrypted_tid = true;
1496 /* encrypted required from now on. */
1497 conn->encrypt_level = Required;
1498 } else if (ENCRYPTION_REQUIRED(conn)) {
1499 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1500 exit_server_cleanly("encryption required "
1501 "on connection");
1502 return conn;
1506 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1507 (flags & (AS_USER|DO_CHDIR)
1508 ?True:False))) {
1509 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1510 return conn;
1512 conn->num_smb_operations++;
1516 * Does this protocol need to be run as guest? (Only archane
1517 * messenger service requests have this...)
1519 if (flags & AS_GUEST) {
1520 char *raddr;
1521 bool ok;
1523 if (!change_to_guest()) {
1524 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1525 return conn;
1528 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1529 talloc_tos());
1530 if (raddr == NULL) {
1531 reply_nterror(req, NT_STATUS_NO_MEMORY);
1532 return conn;
1536 * Haven't we checked this in smbd_process already???
1539 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1540 sconn->remote_hostname, raddr);
1541 TALLOC_FREE(raddr);
1543 if (!ok) {
1544 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1545 return conn;
1549 smb_messages[type].fn(req);
1550 return req->conn;
1553 /****************************************************************************
1554 Construct a reply to the incoming packet.
1555 ****************************************************************************/
1557 static void construct_reply(struct smbd_server_connection *sconn,
1558 char *inbuf, int size, size_t unread_bytes,
1559 uint32_t seqnum, bool encrypted,
1560 struct smb_perfcount_data *deferred_pcd)
1562 connection_struct *conn;
1563 struct smb_request *req;
1565 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1566 smb_panic("could not allocate smb_request");
1569 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1570 encrypted, seqnum)) {
1571 exit_server_cleanly("Invalid SMB request");
1574 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1576 /* we popped this message off the queue - keep original perf data */
1577 if (deferred_pcd)
1578 req->pcd = *deferred_pcd;
1579 else {
1580 SMB_PERFCOUNT_START(&req->pcd);
1581 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1582 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1585 conn = switch_message(req->cmd, req);
1587 if (req->outbuf == NULL) {
1588 return;
1591 if (CVAL(req->outbuf,0) == 0) {
1592 show_msg((char *)req->outbuf);
1595 if (!srv_send_smb(req->sconn,
1596 (char *)req->outbuf,
1597 true, req->seqnum+1,
1598 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1599 &req->pcd)) {
1600 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1603 TALLOC_FREE(req);
1605 return;
1608 static void construct_reply_chain(struct smbd_server_connection *sconn,
1609 char *inbuf, int size, uint32_t seqnum,
1610 bool encrypted,
1611 struct smb_perfcount_data *deferred_pcd)
1613 struct smb_request **reqs = NULL;
1614 struct smb_request *req;
1615 unsigned num_reqs;
1616 bool ok;
1618 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1619 seqnum, &reqs, &num_reqs);
1620 if (!ok) {
1621 char errbuf[smb_size];
1622 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1623 __LINE__, __FILE__);
1624 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1625 NULL)) {
1626 exit_server_cleanly("construct_reply_chain: "
1627 "srv_send_smb failed.");
1629 return;
1632 req = reqs[0];
1633 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1635 req->conn = switch_message(req->cmd, req);
1637 if (req->outbuf == NULL) {
1639 * Request has suspended itself, will come
1640 * back here.
1642 return;
1644 smb_request_done(req);
1648 * To be called from an async SMB handler that is potentially chained
1649 * when it is finished for shipping.
1652 void smb_request_done(struct smb_request *req)
1654 struct smb_request **reqs = NULL;
1655 struct smb_request *first_req;
1656 size_t i, num_reqs, next_index;
1657 NTSTATUS status;
1659 if (req->chain == NULL) {
1660 first_req = req;
1661 goto shipit;
1664 reqs = req->chain;
1665 num_reqs = talloc_array_length(reqs);
1667 for (i=0; i<num_reqs; i++) {
1668 if (reqs[i] == req) {
1669 break;
1672 if (i == num_reqs) {
1674 * Invalid chain, should not happen
1676 status = NT_STATUS_INTERNAL_ERROR;
1677 goto error;
1679 next_index = i+1;
1681 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1682 struct smb_request *next = reqs[next_index];
1683 struct smbXsrv_tcon *tcon;
1684 NTTIME now = timeval_to_nttime(&req->request_time);
1686 next->vuid = SVAL(req->outbuf, smb_uid);
1687 next->tid = SVAL(req->outbuf, smb_tid);
1688 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1689 now, &tcon);
1690 if (NT_STATUS_IS_OK(status)) {
1691 req->conn = tcon->compat;
1692 } else {
1693 req->conn = NULL;
1695 next->chain_fsp = req->chain_fsp;
1696 next->inbuf = (uint8_t *)req->inbuf;
1698 req = next;
1699 req->conn = switch_message(req->cmd, req);
1701 if (req->outbuf == NULL) {
1703 * Request has suspended itself, will come
1704 * back here.
1706 return;
1708 next_index += 1;
1711 first_req = reqs[0];
1713 for (i=1; i<next_index; i++) {
1714 bool ok;
1716 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1717 if (!ok) {
1718 status = NT_STATUS_INTERNAL_ERROR;
1719 goto error;
1723 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1724 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1727 * This scary statement intends to set the
1728 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1729 * to the value last_req->outbuf carries
1731 SSVAL(first_req->outbuf, smb_flg2,
1732 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1733 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1736 * Transfer the error codes from the subrequest to the main one
1738 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1739 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1741 _smb_setlen_large(
1742 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1744 shipit:
1745 if (!srv_send_smb(first_req->sconn,
1746 (char *)first_req->outbuf,
1747 true, first_req->seqnum+1,
1748 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1749 &first_req->pcd)) {
1750 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1751 "failed.");
1753 TALLOC_FREE(req); /* non-chained case */
1754 TALLOC_FREE(reqs); /* chained case */
1755 return;
1757 error:
1759 char errbuf[smb_size];
1760 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1761 if (!srv_send_smb(req->sconn, errbuf, true,
1762 req->seqnum+1, req->encrypted,
1763 NULL)) {
1764 exit_server_cleanly("construct_reply_chain: "
1765 "srv_send_smb failed.");
1768 TALLOC_FREE(req); /* non-chained case */
1769 TALLOC_FREE(reqs); /* chained case */
1772 /****************************************************************************
1773 Process an smb from the client
1774 ****************************************************************************/
1775 static void process_smb(struct smbd_server_connection *sconn,
1776 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1777 uint32_t seqnum, bool encrypted,
1778 struct smb_perfcount_data *deferred_pcd)
1780 int msg_type = CVAL(inbuf,0);
1782 DO_PROFILE_INC(smb_count);
1784 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1785 smb_len(inbuf) ) );
1786 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1787 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1789 if (msg_type != NBSSmessage) {
1791 * NetBIOS session request, keepalive, etc.
1793 reply_special(sconn, (char *)inbuf, nread);
1794 goto done;
1797 if (sconn->using_smb2) {
1798 /* At this point we're not really using smb2,
1799 * we make the decision here.. */
1800 if (smbd_is_smb2_header(inbuf, nread)) {
1801 smbd_smb2_first_negprot(sconn, inbuf, nread);
1802 return;
1803 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1804 && CVAL(inbuf, smb_com) != 0x72) {
1805 /* This is a non-negprot SMB1 packet.
1806 Disable SMB2 from now on. */
1807 sconn->using_smb2 = false;
1811 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1812 * so subtract 4 from it. */
1813 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1814 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1815 smb_len(inbuf)));
1817 /* special magic for immediate exit */
1818 if ((nread == 9) &&
1819 (IVAL(inbuf, 4) == 0x74697865) &&
1820 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1821 uint8_t exitcode = CVAL(inbuf, 8);
1822 DEBUG(1, ("Exiting immediately with code %d\n",
1823 (int)exitcode));
1824 exit(exitcode);
1827 exit_server_cleanly("Non-SMB packet");
1830 show_msg((char *)inbuf);
1832 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1833 construct_reply_chain(sconn, (char *)inbuf, nread,
1834 seqnum, encrypted, deferred_pcd);
1835 } else {
1836 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1837 seqnum, encrypted, deferred_pcd);
1840 sconn->trans_num++;
1842 done:
1843 sconn->num_requests++;
1845 /* The timeout_processing function isn't run nearly
1846 often enough to implement 'max log size' without
1847 overrunning the size of the file by many megabytes.
1848 This is especially true if we are running at debug
1849 level 10. Checking every 50 SMBs is a nice
1850 tradeoff of performance vs log file size overrun. */
1852 if ((sconn->num_requests % 50) == 0 &&
1853 need_to_check_log_size()) {
1854 change_to_root_user();
1855 check_log_size();
1859 /****************************************************************************
1860 Return a string containing the function name of a SMB command.
1861 ****************************************************************************/
1863 const char *smb_fn_name(int type)
1865 const char *unknown_name = "SMBunknown";
1867 if (smb_messages[type].name == NULL)
1868 return(unknown_name);
1870 return(smb_messages[type].name);
1873 /****************************************************************************
1874 Helper functions for contruct_reply.
1875 ****************************************************************************/
1877 void add_to_common_flags2(uint32 v)
1879 common_flags2 |= v;
1882 void remove_from_common_flags2(uint32 v)
1884 common_flags2 &= ~v;
1887 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1888 char *outbuf)
1890 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1891 uint16_t out_flags2 = common_flags2;
1893 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1894 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1895 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1897 srv_set_message(outbuf,0,0,false);
1899 SCVAL(outbuf, smb_com, req->cmd);
1900 SIVAL(outbuf,smb_rcls,0);
1901 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1902 SSVAL(outbuf,smb_flg2, out_flags2);
1903 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1904 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1906 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1907 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1908 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1909 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1912 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1914 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1918 * @brief Find the smb_cmd offset of the last command pushed
1919 * @param[in] buf The buffer we're building up
1920 * @retval Where can we put our next andx cmd?
1922 * While chaining requests, the "next" request we're looking at needs to put
1923 * its SMB_Command before the data the previous request already built up added
1924 * to the chain. Find the offset to the place where we have to put our cmd.
1927 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1929 uint8_t cmd;
1930 size_t ofs;
1932 cmd = CVAL(buf, smb_com);
1934 if (!is_andx_req(cmd)) {
1935 return false;
1938 ofs = smb_vwv0;
1940 while (CVAL(buf, ofs) != 0xff) {
1942 if (!is_andx_req(CVAL(buf, ofs))) {
1943 return false;
1947 * ofs is from start of smb header, so add the 4 length
1948 * bytes. The next cmd is right after the wct field.
1950 ofs = SVAL(buf, ofs+2) + 4 + 1;
1952 if (ofs+4 >= talloc_get_size(buf)) {
1953 return false;
1957 *pofs = ofs;
1958 return true;
1962 * @brief Do the smb chaining at a buffer level
1963 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1964 * @param[in] andx_buf Buffer to be appended
1967 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1969 uint8_t smb_command = CVAL(andx_buf, smb_com);
1970 uint8_t wct = CVAL(andx_buf, smb_wct);
1971 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1972 uint32_t num_bytes = smb_buflen(andx_buf);
1973 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1975 uint8_t *outbuf;
1976 size_t old_size, new_size;
1977 size_t ofs;
1978 size_t chain_padding = 0;
1979 size_t andx_cmd_ofs;
1982 old_size = talloc_get_size(*poutbuf);
1984 if ((old_size % 4) != 0) {
1986 * Align the wct field of subsequent requests to a 4-byte
1987 * boundary
1989 chain_padding = 4 - (old_size % 4);
1993 * After the old request comes the new wct field (1 byte), the vwv's
1994 * and the num_bytes field.
1997 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1998 new_size += num_bytes;
2000 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2001 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2002 (unsigned)new_size));
2003 return false;
2006 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2007 if (outbuf == NULL) {
2008 DEBUG(0, ("talloc failed\n"));
2009 return false;
2011 *poutbuf = outbuf;
2013 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2014 DEBUG(1, ("invalid command chain\n"));
2015 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2016 return false;
2019 if (chain_padding != 0) {
2020 memset(outbuf + old_size, 0, chain_padding);
2021 old_size += chain_padding;
2024 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2025 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2027 ofs = old_size;
2030 * Push the chained request:
2032 * wct field
2035 SCVAL(outbuf, ofs, wct);
2036 ofs += 1;
2039 * vwv array
2042 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2045 * HACK ALERT
2047 * Read&X has an offset into its data buffer at
2048 * vwv[6]. reply_read_andx has no idea anymore that it's
2049 * running from within a chain, so we have to fix up the
2050 * offset here.
2052 * Although it looks disgusting at this place, I want to keep
2053 * it here. The alternative would be to push knowledge about
2054 * the andx chain down into read&x again.
2057 if (smb_command == SMBreadX) {
2058 uint8_t *bytes_addr;
2060 if (wct < 7) {
2062 * Invalid read&x response
2064 return false;
2067 bytes_addr = outbuf + ofs /* vwv start */
2068 + sizeof(uint16_t) * wct /* vwv array */
2069 + sizeof(uint16_t); /* bcc */
2071 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2072 bytes_addr - outbuf - 4);
2075 ofs += sizeof(uint16_t) * wct;
2078 * bcc (byte count)
2081 SSVAL(outbuf, ofs, num_bytes);
2082 ofs += sizeof(uint16_t);
2085 * The bytes field
2088 memcpy(outbuf + ofs, bytes, num_bytes);
2090 return true;
2093 bool smb1_is_chain(const uint8_t *buf)
2095 uint8_t cmd, wct, andx_cmd;
2097 cmd = CVAL(buf, smb_com);
2098 if (!is_andx_req(cmd)) {
2099 return false;
2101 wct = CVAL(buf, smb_wct);
2102 if (wct < 2) {
2103 return false;
2105 andx_cmd = CVAL(buf, smb_vwv);
2106 return (andx_cmd != 0xFF);
2109 bool smb1_walk_chain(const uint8_t *buf,
2110 bool (*fn)(uint8_t cmd,
2111 uint8_t wct, const uint16_t *vwv,
2112 uint16_t num_bytes, const uint8_t *bytes,
2113 void *private_data),
2114 void *private_data)
2116 size_t smblen = smb_len(buf);
2117 const char *smb_buf = smb_base(buf);
2118 uint8_t cmd, chain_cmd;
2119 uint8_t wct;
2120 const uint16_t *vwv;
2121 uint16_t num_bytes;
2122 const uint8_t *bytes;
2124 cmd = CVAL(buf, smb_com);
2125 wct = CVAL(buf, smb_wct);
2126 vwv = (const uint16_t *)(buf + smb_vwv);
2127 num_bytes = smb_buflen(buf);
2128 bytes = (uint8_t *)smb_buf_const(buf);
2130 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2131 return false;
2134 if (!is_andx_req(cmd)) {
2135 return true;
2137 if (wct < 2) {
2138 return false;
2141 chain_cmd = CVAL(vwv, 0);
2143 while (chain_cmd != 0xff) {
2144 uint32_t chain_offset; /* uint32_t to avoid overflow */
2145 size_t length_needed;
2146 ptrdiff_t vwv_offset;
2148 chain_offset = SVAL(vwv+1, 0);
2151 * Check if the client tries to fool us. The chain
2152 * offset needs to point beyond the current request in
2153 * the chain, it needs to strictly grow. Otherwise we
2154 * might be tricked into an endless loop always
2155 * processing the same request over and over again. We
2156 * used to assume that vwv and the byte buffer array
2157 * in a chain are always attached, but OS/2 the
2158 * Write&X/Read&X chain puts the Read&X vwv array
2159 * right behind the Write&X vwv chain. The Write&X bcc
2160 * array is put behind the Read&X vwv array. So now we
2161 * check whether the chain offset points strictly
2162 * behind the previous vwv array. req->buf points
2163 * right after the vwv array of the previous
2164 * request. See
2165 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2166 * more information.
2169 vwv_offset = ((const char *)vwv - smb_buf);
2170 if (chain_offset <= vwv_offset) {
2171 return false;
2175 * Next check: Make sure the chain offset does not
2176 * point beyond the overall smb request length.
2179 length_needed = chain_offset+1; /* wct */
2180 if (length_needed > smblen) {
2181 return false;
2185 * Now comes the pointer magic. Goal here is to set up
2186 * vwv and buf correctly again. The chain offset (the
2187 * former vwv[1]) points at the new wct field.
2190 wct = CVAL(smb_buf, chain_offset);
2192 if (is_andx_req(chain_cmd) && (wct < 2)) {
2193 return false;
2197 * Next consistency check: Make the new vwv array fits
2198 * in the overall smb request.
2201 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2202 if (length_needed > smblen) {
2203 return false;
2205 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2208 * Now grab the new byte buffer....
2211 num_bytes = SVAL(vwv+wct, 0);
2214 * .. and check that it fits.
2217 length_needed += num_bytes;
2218 if (length_needed > smblen) {
2219 return false;
2221 bytes = (const uint8_t *)(vwv+wct+1);
2223 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2224 return false;
2227 if (!is_andx_req(chain_cmd)) {
2228 return true;
2230 chain_cmd = CVAL(vwv, 0);
2232 return true;
2235 static bool smb1_chain_length_cb(uint8_t cmd,
2236 uint8_t wct, const uint16_t *vwv,
2237 uint16_t num_bytes, const uint8_t *bytes,
2238 void *private_data)
2240 unsigned *count = (unsigned *)private_data;
2241 *count += 1;
2242 return true;
2245 unsigned smb1_chain_length(const uint8_t *buf)
2247 unsigned count = 0;
2249 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2250 return 0;
2252 return count;
2255 struct smb1_parse_chain_state {
2256 TALLOC_CTX *mem_ctx;
2257 const uint8_t *buf;
2258 struct smbd_server_connection *sconn;
2259 bool encrypted;
2260 uint32_t seqnum;
2262 struct smb_request **reqs;
2263 unsigned num_reqs;
2266 static bool smb1_parse_chain_cb(uint8_t cmd,
2267 uint8_t wct, const uint16_t *vwv,
2268 uint16_t num_bytes, const uint8_t *bytes,
2269 void *private_data)
2271 struct smb1_parse_chain_state *state =
2272 (struct smb1_parse_chain_state *)private_data;
2273 struct smb_request **reqs;
2274 struct smb_request *req;
2275 bool ok;
2277 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2278 struct smb_request *, state->num_reqs+1);
2279 if (reqs == NULL) {
2280 return false;
2282 state->reqs = reqs;
2284 req = talloc(reqs, struct smb_request);
2285 if (req == NULL) {
2286 return false;
2289 ok = init_smb_request(req, state->sconn, state->buf, 0,
2290 state->encrypted, state->seqnum);
2291 if (!ok) {
2292 return false;
2294 req->cmd = cmd;
2295 req->wct = wct;
2296 req->vwv = vwv;
2297 req->buflen = num_bytes;
2298 req->buf = bytes;
2300 reqs[state->num_reqs] = req;
2301 state->num_reqs += 1;
2302 return true;
2305 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2306 struct smbd_server_connection *sconn,
2307 bool encrypted, uint32_t seqnum,
2308 struct smb_request ***reqs, unsigned *num_reqs)
2310 struct smb1_parse_chain_state state;
2311 unsigned i;
2313 state.mem_ctx = mem_ctx;
2314 state.buf = buf;
2315 state.sconn = sconn;
2316 state.encrypted = encrypted;
2317 state.seqnum = seqnum;
2318 state.reqs = NULL;
2319 state.num_reqs = 0;
2321 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2322 TALLOC_FREE(state.reqs);
2323 return false;
2325 for (i=0; i<state.num_reqs; i++) {
2326 state.reqs[i]->chain = state.reqs;
2328 *reqs = state.reqs;
2329 *num_reqs = state.num_reqs;
2330 return true;
2333 /****************************************************************************
2334 Check if services need reloading.
2335 ****************************************************************************/
2337 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2340 if (last_smb_conf_reload_time == 0) {
2341 last_smb_conf_reload_time = t;
2344 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2345 reload_services(sconn, conn_snum_used, true);
2346 last_smb_conf_reload_time = t;
2350 static bool fd_is_readable(int fd)
2352 int ret, revents;
2354 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2356 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2360 static void smbd_server_connection_write_handler(
2361 struct smbd_server_connection *sconn)
2363 /* TODO: make write nonblocking */
2366 static void smbd_server_connection_read_handler(
2367 struct smbd_server_connection *sconn, int fd)
2369 uint8_t *inbuf = NULL;
2370 size_t inbuf_len = 0;
2371 size_t unread_bytes = 0;
2372 bool encrypted = false;
2373 TALLOC_CTX *mem_ctx = talloc_tos();
2374 NTSTATUS status;
2375 uint32_t seqnum;
2377 bool from_client;
2379 if (lp_async_smb_echo_handler()
2380 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2382 * This is the super-ugly hack to prefer the packets
2383 * forwarded by the echo handler over the ones by the
2384 * client directly
2386 fd = sconn->smb1.echo_handler.trusted_fd;
2389 from_client = (sconn->sock == fd);
2391 if (from_client) {
2392 smbd_lock_socket(sconn);
2394 if (!fd_is_readable(fd)) {
2395 DEBUG(10,("the echo listener was faster\n"));
2396 smbd_unlock_socket(sconn);
2397 return;
2401 /* TODO: make this completely nonblocking */
2402 status = receive_smb_talloc(mem_ctx, sconn, fd,
2403 (char **)(void *)&inbuf,
2404 0, /* timeout */
2405 &unread_bytes,
2406 &encrypted,
2407 &inbuf_len, &seqnum,
2408 false /* trusted channel */);
2410 if (from_client) {
2411 smbd_unlock_socket(sconn);
2414 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2415 goto process;
2417 if (NT_STATUS_IS_ERR(status)) {
2418 exit_server_cleanly("failed to receive smb request");
2420 if (!NT_STATUS_IS_OK(status)) {
2421 return;
2424 process:
2425 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2426 seqnum, encrypted, NULL);
2429 static void smbd_server_connection_handler(struct event_context *ev,
2430 struct fd_event *fde,
2431 uint16_t flags,
2432 void *private_data)
2434 struct smbd_server_connection *conn = talloc_get_type(private_data,
2435 struct smbd_server_connection);
2437 if (flags & EVENT_FD_WRITE) {
2438 smbd_server_connection_write_handler(conn);
2439 return;
2441 if (flags & EVENT_FD_READ) {
2442 smbd_server_connection_read_handler(conn, conn->sock);
2443 return;
2447 static void smbd_server_echo_handler(struct event_context *ev,
2448 struct fd_event *fde,
2449 uint16_t flags,
2450 void *private_data)
2452 struct smbd_server_connection *conn = talloc_get_type(private_data,
2453 struct smbd_server_connection);
2455 if (flags & EVENT_FD_WRITE) {
2456 smbd_server_connection_write_handler(conn);
2457 return;
2459 if (flags & EVENT_FD_READ) {
2460 smbd_server_connection_read_handler(
2461 conn, conn->smb1.echo_handler.trusted_fd);
2462 return;
2466 #ifdef CLUSTER_SUPPORT
2467 /****************************************************************************
2468 received when we should release a specific IP
2469 ****************************************************************************/
2470 static void release_ip(const char *ip, void *priv)
2472 const char *addr = (const char *)priv;
2473 const char *p = addr;
2475 if (strncmp("::ffff:", addr, 7) == 0) {
2476 p = addr + 7;
2479 DEBUG(10, ("Got release IP message for %s, "
2480 "our address is %s\n", ip, p));
2482 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2483 /* we can't afford to do a clean exit - that involves
2484 database writes, which would potentially mean we
2485 are still running after the failover has finished -
2486 we have to get rid of this process ID straight
2487 away */
2488 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2489 ip));
2490 /* note we must exit with non-zero status so the unclean handler gets
2491 called in the parent, so that the brl database is tickled */
2492 _exit(1);
2496 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2497 struct sockaddr_storage *client)
2499 socklen_t length;
2500 length = sizeof(*server);
2501 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2502 return -1;
2504 length = sizeof(*client);
2505 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2506 return -1;
2508 return 0;
2510 #endif
2513 * Send keepalive packets to our client
2515 static bool keepalive_fn(const struct timeval *now, void *private_data)
2517 struct smbd_server_connection *sconn = talloc_get_type_abort(
2518 private_data, struct smbd_server_connection);
2519 bool ret;
2521 if (sconn->using_smb2) {
2522 /* Don't do keepalives on an SMB2 connection. */
2523 return false;
2526 smbd_lock_socket(sconn);
2527 ret = send_keepalive(sconn->sock);
2528 smbd_unlock_socket(sconn);
2530 if (!ret) {
2531 char addr[INET6_ADDRSTRLEN];
2533 * Try and give an error message saying what
2534 * client failed.
2536 DEBUG(0, ("send_keepalive failed for client %s. "
2537 "Error %s - exiting\n",
2538 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2539 strerror(errno)));
2540 return False;
2542 return True;
2546 * Do the recurring check if we're idle
2548 static bool deadtime_fn(const struct timeval *now, void *private_data)
2550 struct smbd_server_connection *sconn =
2551 (struct smbd_server_connection *)private_data;
2553 if ((conn_num_open(sconn) == 0)
2554 || (conn_idle_all(sconn, now->tv_sec))) {
2555 DEBUG( 2, ( "Closing idle connection\n" ) );
2556 messaging_send(sconn->msg_ctx,
2557 messaging_server_id(sconn->msg_ctx),
2558 MSG_SHUTDOWN, &data_blob_null);
2559 return False;
2562 return True;
2566 * Do the recurring log file and smb.conf reload checks.
2569 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2571 struct smbd_server_connection *sconn = talloc_get_type_abort(
2572 private_data, struct smbd_server_connection);
2574 DEBUG(5, ("housekeeping\n"));
2576 change_to_root_user();
2578 /* update printer queue caches if necessary */
2579 update_monitored_printq_cache(sconn->msg_ctx);
2581 /* check if we need to reload services */
2582 check_reload(sconn, time_mono(NULL));
2584 /* Change machine password if neccessary. */
2585 attempt_machine_password_change();
2588 * Force a log file check.
2590 force_check_log_size();
2591 check_log_size();
2592 return true;
2596 * Read an smb packet in the echo handler child, giving the parent
2597 * smbd one second to react once the socket becomes readable.
2600 struct smbd_echo_read_state {
2601 struct tevent_context *ev;
2602 struct smbd_server_connection *sconn;
2604 char *buf;
2605 size_t buflen;
2606 uint32_t seqnum;
2609 static void smbd_echo_read_readable(struct tevent_req *subreq);
2610 static void smbd_echo_read_waited(struct tevent_req *subreq);
2612 static struct tevent_req *smbd_echo_read_send(
2613 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2614 struct smbd_server_connection *sconn)
2616 struct tevent_req *req, *subreq;
2617 struct smbd_echo_read_state *state;
2619 req = tevent_req_create(mem_ctx, &state,
2620 struct smbd_echo_read_state);
2621 if (req == NULL) {
2622 return NULL;
2624 state->ev = ev;
2625 state->sconn = sconn;
2627 subreq = wait_for_read_send(state, ev, sconn->sock);
2628 if (tevent_req_nomem(subreq, req)) {
2629 return tevent_req_post(req, ev);
2631 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2632 return req;
2635 static void smbd_echo_read_readable(struct tevent_req *subreq)
2637 struct tevent_req *req = tevent_req_callback_data(
2638 subreq, struct tevent_req);
2639 struct smbd_echo_read_state *state = tevent_req_data(
2640 req, struct smbd_echo_read_state);
2641 bool ok;
2642 int err;
2644 ok = wait_for_read_recv(subreq, &err);
2645 TALLOC_FREE(subreq);
2646 if (!ok) {
2647 tevent_req_nterror(req, map_nt_error_from_unix(err));
2648 return;
2652 * Give the parent smbd one second to step in
2655 subreq = tevent_wakeup_send(
2656 state, state->ev, timeval_current_ofs(1, 0));
2657 if (tevent_req_nomem(subreq, req)) {
2658 return;
2660 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2663 static void smbd_echo_read_waited(struct tevent_req *subreq)
2665 struct tevent_req *req = tevent_req_callback_data(
2666 subreq, struct tevent_req);
2667 struct smbd_echo_read_state *state = tevent_req_data(
2668 req, struct smbd_echo_read_state);
2669 struct smbd_server_connection *sconn = state->sconn;
2670 bool ok;
2671 NTSTATUS status;
2672 size_t unread = 0;
2673 bool encrypted;
2675 ok = tevent_wakeup_recv(subreq);
2676 TALLOC_FREE(subreq);
2677 if (!ok) {
2678 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2679 return;
2682 ok = smbd_lock_socket_internal(sconn);
2683 if (!ok) {
2684 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2685 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2686 return;
2689 if (!fd_is_readable(sconn->sock)) {
2690 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2691 (int)getpid()));
2693 ok = smbd_unlock_socket_internal(sconn);
2694 if (!ok) {
2695 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2696 DEBUG(1, ("%s: failed to unlock socket\n",
2697 __location__));
2698 return;
2701 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2702 if (tevent_req_nomem(subreq, req)) {
2703 return;
2705 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2706 return;
2709 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2710 0 /* timeout */,
2711 &unread,
2712 &encrypted,
2713 &state->buflen,
2714 &state->seqnum,
2715 false /* trusted_channel*/);
2717 if (tevent_req_nterror(req, status)) {
2718 tevent_req_nterror(req, status);
2719 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2720 (int)getpid(), nt_errstr(status)));
2721 return;
2724 ok = smbd_unlock_socket_internal(sconn);
2725 if (!ok) {
2726 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2727 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2728 return;
2730 tevent_req_done(req);
2733 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2734 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2736 struct smbd_echo_read_state *state = tevent_req_data(
2737 req, struct smbd_echo_read_state);
2738 NTSTATUS status;
2740 if (tevent_req_is_nterror(req, &status)) {
2741 return status;
2743 *pbuf = talloc_move(mem_ctx, &state->buf);
2744 *pbuflen = state->buflen;
2745 *pseqnum = state->seqnum;
2746 return NT_STATUS_OK;
2749 struct smbd_echo_state {
2750 struct tevent_context *ev;
2751 struct iovec *pending;
2752 struct smbd_server_connection *sconn;
2753 int parent_pipe;
2755 struct tevent_fd *parent_fde;
2757 struct tevent_req *write_req;
2760 static void smbd_echo_writer_done(struct tevent_req *req);
2762 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2764 int num_pending;
2766 if (state->write_req != NULL) {
2767 return;
2770 num_pending = talloc_array_length(state->pending);
2771 if (num_pending == 0) {
2772 return;
2775 state->write_req = writev_send(state, state->ev, NULL,
2776 state->parent_pipe, false,
2777 state->pending, num_pending);
2778 if (state->write_req == NULL) {
2779 DEBUG(1, ("writev_send failed\n"));
2780 exit(1);
2783 talloc_steal(state->write_req, state->pending);
2784 state->pending = NULL;
2786 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2787 state);
2790 static void smbd_echo_writer_done(struct tevent_req *req)
2792 struct smbd_echo_state *state = tevent_req_callback_data(
2793 req, struct smbd_echo_state);
2794 ssize_t written;
2795 int err;
2797 written = writev_recv(req, &err);
2798 TALLOC_FREE(req);
2799 state->write_req = NULL;
2800 if (written == -1) {
2801 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2802 exit(1);
2804 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2805 smbd_echo_activate_writer(state);
2808 static bool smbd_echo_reply(struct smbd_echo_state *state,
2809 uint8_t *inbuf, size_t inbuf_len,
2810 uint32_t seqnum)
2812 struct smb_request req;
2813 uint16_t num_replies;
2814 char *outbuf;
2815 bool ok;
2817 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2818 DEBUG(10, ("Got netbios keepalive\n"));
2820 * Just swallow it
2822 return true;
2825 if (inbuf_len < smb_size) {
2826 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2827 return false;
2829 if (!valid_smb_header(state->sconn, inbuf)) {
2830 DEBUG(10, ("Got invalid SMB header\n"));
2831 return false;
2834 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2835 seqnum)) {
2836 return false;
2838 req.inbuf = inbuf;
2840 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2841 smb_messages[req.cmd].name
2842 ? smb_messages[req.cmd].name : "unknown"));
2844 if (req.cmd != SMBecho) {
2845 return false;
2847 if (req.wct < 1) {
2848 return false;
2851 num_replies = SVAL(req.vwv+0, 0);
2852 if (num_replies != 1) {
2853 /* Not a Windows "Hey, you're still there?" request */
2854 return false;
2857 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2858 1, req.buflen)) {
2859 DEBUG(10, ("create_outbuf failed\n"));
2860 return false;
2862 req.outbuf = (uint8_t *)outbuf;
2864 SSVAL(req.outbuf, smb_vwv0, num_replies);
2866 if (req.buflen > 0) {
2867 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2870 ok = srv_send_smb(req.sconn,
2871 (char *)outbuf,
2872 true, seqnum+1,
2873 false, &req.pcd);
2874 TALLOC_FREE(outbuf);
2875 if (!ok) {
2876 exit(1);
2879 return true;
2882 static void smbd_echo_exit(struct tevent_context *ev,
2883 struct tevent_fd *fde, uint16_t flags,
2884 void *private_data)
2886 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2887 exit(0);
2890 static void smbd_echo_got_packet(struct tevent_req *req);
2892 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2893 int parent_pipe)
2895 struct smbd_echo_state *state;
2896 struct tevent_req *read_req;
2898 state = talloc_zero(sconn, struct smbd_echo_state);
2899 if (state == NULL) {
2900 DEBUG(1, ("talloc failed\n"));
2901 return;
2903 state->sconn = sconn;
2904 state->parent_pipe = parent_pipe;
2905 state->ev = s3_tevent_context_init(state);
2906 if (state->ev == NULL) {
2907 DEBUG(1, ("tevent_context_init failed\n"));
2908 TALLOC_FREE(state);
2909 return;
2911 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2912 TEVENT_FD_READ, smbd_echo_exit,
2913 state);
2914 if (state->parent_fde == NULL) {
2915 DEBUG(1, ("tevent_add_fd failed\n"));
2916 TALLOC_FREE(state);
2917 return;
2920 read_req = smbd_echo_read_send(state, state->ev, sconn);
2921 if (read_req == NULL) {
2922 DEBUG(1, ("smbd_echo_read_send failed\n"));
2923 TALLOC_FREE(state);
2924 return;
2926 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2928 while (true) {
2929 if (tevent_loop_once(state->ev) == -1) {
2930 DEBUG(1, ("tevent_loop_once failed: %s\n",
2931 strerror(errno)));
2932 break;
2935 TALLOC_FREE(state);
2938 static void smbd_echo_got_packet(struct tevent_req *req)
2940 struct smbd_echo_state *state = tevent_req_callback_data(
2941 req, struct smbd_echo_state);
2942 NTSTATUS status;
2943 char *buf = NULL;
2944 size_t buflen = 0;
2945 uint32_t seqnum = 0;
2946 bool reply;
2948 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2949 TALLOC_FREE(req);
2950 if (!NT_STATUS_IS_OK(status)) {
2951 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2952 nt_errstr(status)));
2953 exit(1);
2956 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2957 if (!reply) {
2958 size_t num_pending;
2959 struct iovec *tmp;
2960 struct iovec *iov;
2962 num_pending = talloc_array_length(state->pending);
2963 tmp = talloc_realloc(state, state->pending, struct iovec,
2964 num_pending+1);
2965 if (tmp == NULL) {
2966 DEBUG(1, ("talloc_realloc failed\n"));
2967 exit(1);
2969 state->pending = tmp;
2971 if (buflen >= smb_size) {
2973 * place the seqnum in the packet so that the main process
2974 * can reply with signing
2976 SIVAL(buf, smb_ss_field, seqnum);
2977 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2980 iov = &state->pending[num_pending];
2981 iov->iov_base = buf;
2982 iov->iov_len = buflen;
2984 DEBUG(10,("echo_handler[%d]: forward to main\n",
2985 (int)getpid()));
2986 smbd_echo_activate_writer(state);
2989 req = smbd_echo_read_send(state, state->ev, state->sconn);
2990 if (req == NULL) {
2991 DEBUG(1, ("smbd_echo_read_send failed\n"));
2992 exit(1);
2994 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2999 * Handle SMBecho requests in a forked child process
3001 bool fork_echo_handler(struct smbd_server_connection *sconn)
3003 int listener_pipe[2];
3004 int res;
3005 pid_t child;
3007 res = pipe(listener_pipe);
3008 if (res == -1) {
3009 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3010 return false;
3012 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3013 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3014 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3015 goto fail;
3018 child = fork();
3019 if (child == 0) {
3020 NTSTATUS status;
3022 close(listener_pipe[0]);
3023 set_blocking(listener_pipe[1], false);
3025 status = reinit_after_fork(sconn->msg_ctx,
3026 sconn->ev_ctx,
3027 false);
3028 if (!NT_STATUS_IS_OK(status)) {
3029 DEBUG(1, ("reinit_after_fork failed: %s\n",
3030 nt_errstr(status)));
3031 exit(1);
3033 smbd_echo_loop(sconn, listener_pipe[1]);
3034 exit(0);
3036 close(listener_pipe[1]);
3037 listener_pipe[1] = -1;
3038 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3040 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
3043 * Without smb signing this is the same as the normal smbd
3044 * listener. This needs to change once signing comes in.
3046 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3047 sconn,
3048 sconn->smb1.echo_handler.trusted_fd,
3049 TEVENT_FD_READ,
3050 smbd_server_echo_handler,
3051 sconn);
3052 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3053 DEBUG(1, ("event_add_fd failed\n"));
3054 goto fail;
3057 return true;
3059 fail:
3060 if (listener_pipe[0] != -1) {
3061 close(listener_pipe[0]);
3063 if (listener_pipe[1] != -1) {
3064 close(listener_pipe[1]);
3066 sconn->smb1.echo_handler.trusted_fd = -1;
3067 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3068 close(sconn->smb1.echo_handler.socket_lock_fd);
3070 sconn->smb1.echo_handler.trusted_fd = -1;
3071 sconn->smb1.echo_handler.socket_lock_fd = -1;
3072 return false;
3075 #if CLUSTER_SUPPORT
3077 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
3078 struct sockaddr_storage *srv,
3079 struct sockaddr_storage *clnt)
3081 struct ctdbd_connection *cconn;
3082 char tmp_addr[INET6_ADDRSTRLEN];
3083 char *addr;
3085 cconn = messaging_ctdbd_connection();
3086 if (cconn == NULL) {
3087 return NT_STATUS_NO_MEMORY;
3090 if (client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr)) == NULL) {
3091 return NT_STATUS_NO_MEMORY;
3093 addr = talloc_strdup(cconn, tmp_addr);
3094 if (addr == NULL) {
3095 return NT_STATUS_NO_MEMORY;
3097 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
3100 #endif
3102 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3104 while (user) {
3105 if (user->session_info &&
3106 (user->session_info->unix_token->uid == uid)) {
3107 return true;
3109 user = user->next;
3111 return false;
3114 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3116 while (user) {
3117 if (user->session_info != NULL) {
3118 int i;
3119 struct security_unix_token *utok;
3121 utok = user->session_info->unix_token;
3122 if (utok->gid == gid) {
3123 return true;
3125 for(i=0; i<utok->ngroups; i++) {
3126 if (utok->groups[i] == gid) {
3127 return true;
3131 user = user->next;
3133 return false;
3136 static bool sid_in_use(const struct user_struct *user,
3137 const struct dom_sid *psid)
3139 while (user) {
3140 struct security_token *tok;
3142 if (user->session_info == NULL) {
3143 continue;
3145 tok = user->session_info->security_token;
3146 if (tok == NULL) {
3148 * Not sure session_info->security_token can
3149 * ever be NULL. This check might be not
3150 * necessary.
3152 continue;
3154 if (security_token_has_sid(tok, psid)) {
3155 return true;
3157 user = user->next;
3159 return false;
3162 static bool id_in_use(const struct user_struct *user,
3163 const struct id_cache_ref *id)
3165 switch(id->type) {
3166 case UID:
3167 return uid_in_use(user, id->id.uid);
3168 case GID:
3169 return gid_in_use(user, id->id.gid);
3170 case SID:
3171 return sid_in_use(user, &id->id.sid);
3172 default:
3173 break;
3175 return false;
3178 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3179 void *private_data,
3180 uint32_t msg_type,
3181 struct server_id server_id,
3182 DATA_BLOB* data)
3184 const char *msg = (data && data->data)
3185 ? (const char *)data->data : "<NULL>";
3186 struct id_cache_ref id;
3187 struct smbd_server_connection *sconn =
3188 talloc_get_type_abort(private_data,
3189 struct smbd_server_connection);
3191 if (!id_cache_ref_parse(msg, &id)) {
3192 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3193 return;
3196 if (id_in_use(sconn->users, &id)) {
3197 exit_server_cleanly(msg);
3199 id_cache_delete_from_cache(&id);
3202 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3203 enum protocol_types protocol)
3205 NTSTATUS status;
3207 set_Protocol(protocol);
3208 conn->protocol = protocol;
3210 if (protocol >= PROTOCOL_SMB2_02) {
3211 status = smb2srv_session_table_init(conn);
3212 if (!NT_STATUS_IS_OK(status)) {
3213 return status;
3216 status = smb2srv_open_table_init(conn);
3217 if (!NT_STATUS_IS_OK(status)) {
3218 return status;
3220 } else {
3221 status = smb1srv_session_table_init(conn);
3222 if (!NT_STATUS_IS_OK(status)) {
3223 return status;
3226 status = smb1srv_tcon_table_init(conn);
3227 if (!NT_STATUS_IS_OK(status)) {
3228 return status;
3231 status = smb1srv_open_table_init(conn);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 return status;
3237 return NT_STATUS_OK;
3240 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3241 void *private_data)
3243 struct smbXsrv_connection *conn =
3244 talloc_get_type_abort(private_data,
3245 struct smbXsrv_connection);
3247 switch (point) {
3248 case TEVENT_TRACE_BEFORE_WAIT:
3250 * This just removes compiler warning
3251 * without profile support
3253 conn->smbd_idle_profstamp = 0;
3254 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3255 break;
3256 case TEVENT_TRACE_AFTER_WAIT:
3257 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3258 break;
3262 /****************************************************************************
3263 Process commands from the client
3264 ****************************************************************************/
3266 void smbd_process(struct tevent_context *ev_ctx,
3267 struct messaging_context *msg_ctx,
3268 int sock_fd,
3269 bool interactive)
3271 TALLOC_CTX *frame = talloc_stackframe();
3272 struct smbXsrv_connection *conn;
3273 struct smbd_server_connection *sconn;
3274 struct sockaddr_storage ss;
3275 struct sockaddr *sa = NULL;
3276 socklen_t sa_socklen;
3277 struct tsocket_address *local_address = NULL;
3278 struct tsocket_address *remote_address = NULL;
3279 const char *locaddr = NULL;
3280 const char *remaddr = NULL;
3281 char *rhost;
3282 int ret;
3284 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3285 if (conn == NULL) {
3286 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3287 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3290 conn->ev_ctx = ev_ctx;
3291 conn->msg_ctx = msg_ctx;
3293 sconn = talloc_zero(conn, struct smbd_server_connection);
3294 if (!sconn) {
3295 exit_server("failed to create smbd_server_connection");
3298 conn->sconn = sconn;
3299 sconn->conn = conn;
3302 * TODO: remove this...:-)
3304 global_smbXsrv_connection = conn;
3306 sconn->ev_ctx = ev_ctx;
3307 sconn->msg_ctx = msg_ctx;
3308 sconn->sock = sock_fd;
3309 sconn->smb1.echo_handler.trusted_fd = -1;
3310 sconn->smb1.echo_handler.socket_lock_fd = -1;
3312 if (!interactive) {
3313 smbd_setup_sig_term_handler(sconn);
3314 smbd_setup_sig_hup_handler(sconn);
3316 if (!serverid_register(messaging_server_id(msg_ctx),
3317 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3318 |FLAG_MSG_DBWRAP
3319 |FLAG_MSG_PRINT_GENERAL)) {
3320 exit_server_cleanly("Could not register myself in "
3321 "serverid.tdb");
3325 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3327 * We're not making the decision here,
3328 * we're just allowing the client
3329 * to decide between SMB1 and SMB2
3330 * with the first negprot
3331 * packet.
3333 sconn->using_smb2 = true;
3336 /* Ensure child is set to blocking mode */
3337 set_blocking(sconn->sock,True);
3339 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3340 set_socket_options(sconn->sock, lp_socket_options());
3342 sa = (struct sockaddr *)(void *)&ss;
3343 sa_socklen = sizeof(ss);
3344 ret = getpeername(sconn->sock, sa, &sa_socklen);
3345 if (ret != 0) {
3346 int level = (errno == ENOTCONN)?2:0;
3347 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3348 exit_server_cleanly("getpeername() failed.\n");
3350 ret = tsocket_address_bsd_from_sockaddr(sconn,
3351 sa, sa_socklen,
3352 &remote_address);
3353 if (ret != 0) {
3354 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3355 __location__, strerror(errno)));
3356 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3359 sa = (struct sockaddr *)(void *)&ss;
3360 sa_socklen = sizeof(ss);
3361 ret = getsockname(sconn->sock, sa, &sa_socklen);
3362 if (ret != 0) {
3363 int level = (errno == ENOTCONN)?2:0;
3364 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3365 exit_server_cleanly("getsockname() failed.\n");
3367 ret = tsocket_address_bsd_from_sockaddr(sconn,
3368 sa, sa_socklen,
3369 &local_address);
3370 if (ret != 0) {
3371 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3372 __location__, strerror(errno)));
3373 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3376 sconn->local_address = local_address;
3377 sconn->remote_address = remote_address;
3379 if (tsocket_address_is_inet(local_address, "ip")) {
3380 locaddr = tsocket_address_inet_addr_string(
3381 sconn->local_address,
3382 talloc_tos());
3383 if (locaddr == NULL) {
3384 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3385 __location__, strerror(errno)));
3386 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3388 } else {
3389 locaddr = "0.0.0.0";
3392 if (tsocket_address_is_inet(remote_address, "ip")) {
3393 remaddr = tsocket_address_inet_addr_string(
3394 sconn->remote_address,
3395 talloc_tos());
3396 if (remaddr == NULL) {
3397 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3398 __location__, strerror(errno)));
3399 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3401 } else {
3402 remaddr = "0.0.0.0";
3405 /* this is needed so that we get decent entries
3406 in smbstatus for port 445 connects */
3407 set_remote_machine_name(remaddr, false);
3408 reload_services(sconn, conn_snum_used, true);
3411 * Before the first packet, check the global hosts allow/ hosts deny
3412 * parameters before doing any parsing of packets passed to us by the
3413 * client. This prevents attacks on our parsing code from hosts not in
3414 * the hosts allow list.
3417 ret = get_remote_hostname(remote_address,
3418 &rhost,
3419 talloc_tos());
3420 if (ret < 0) {
3421 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3422 __location__, strerror(errno)));
3423 exit_server_cleanly("get_remote_hostname failed.\n");
3425 if (strequal(rhost, "UNKNOWN")) {
3426 rhost = talloc_strdup(talloc_tos(), remaddr);
3428 sconn->remote_hostname = talloc_move(sconn, &rhost);
3430 sub_set_socket_ids(remaddr,
3431 sconn->remote_hostname,
3432 locaddr);
3434 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3435 sconn->remote_hostname,
3436 remaddr)) {
3438 * send a negative session response "not listening on calling
3439 * name"
3441 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3442 DEBUG( 1, ("Connection denied from %s to %s\n",
3443 tsocket_address_string(remote_address, talloc_tos()),
3444 tsocket_address_string(local_address, talloc_tos())));
3445 (void)srv_send_smb(sconn,(char *)buf, false,
3446 0, false, NULL);
3447 exit_server_cleanly("connection denied");
3450 DEBUG(10, ("Connection allowed from %s to %s\n",
3451 tsocket_address_string(remote_address, talloc_tos()),
3452 tsocket_address_string(local_address, talloc_tos())));
3454 if (lp_preload_modules()) {
3455 smb_load_modules(lp_preload_modules());
3458 smb_perfcount_init();
3460 if (!init_account_policy()) {
3461 exit_server("Could not open account policy tdb.\n");
3464 if (*lp_rootdir()) {
3465 if (chroot(lp_rootdir()) != 0) {
3466 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3467 exit_server("Failed to chroot()");
3469 if (chdir("/") == -1) {
3470 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3471 exit_server("Failed to chroot()");
3473 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3476 if (!srv_init_signing(sconn)) {
3477 exit_server("Failed to init smb_signing");
3480 if (!file_init(sconn)) {
3481 exit_server("file_init() failed");
3484 /* Setup oplocks */
3485 if (!init_oplocks(sconn))
3486 exit_server("Failed to init oplocks");
3488 /* register our message handlers */
3489 messaging_register(sconn->msg_ctx, sconn,
3490 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3491 messaging_register(sconn->msg_ctx, sconn,
3492 MSG_SMB_CLOSE_FILE, msg_close_file);
3493 messaging_register(sconn->msg_ctx, sconn,
3494 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3496 id_cache_register_msgs(sconn->msg_ctx);
3497 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3498 messaging_register(sconn->msg_ctx, sconn,
3499 ID_CACHE_KILL, smbd_id_cache_kill);
3501 messaging_deregister(sconn->msg_ctx,
3502 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3503 messaging_register(sconn->msg_ctx, sconn,
3504 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3507 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3508 * MSGs to all child processes
3510 messaging_deregister(sconn->msg_ctx,
3511 MSG_DEBUG, NULL);
3512 messaging_register(sconn->msg_ctx, NULL,
3513 MSG_DEBUG, debug_message);
3515 if ((lp_keepalive() != 0)
3516 && !(event_add_idle(ev_ctx, NULL,
3517 timeval_set(lp_keepalive(), 0),
3518 "keepalive", keepalive_fn,
3519 sconn))) {
3520 DEBUG(0, ("Could not add keepalive event\n"));
3521 exit(1);
3524 if (!(event_add_idle(ev_ctx, NULL,
3525 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3526 "deadtime", deadtime_fn, sconn))) {
3527 DEBUG(0, ("Could not add deadtime event\n"));
3528 exit(1);
3531 if (!(event_add_idle(ev_ctx, NULL,
3532 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3533 "housekeeping", housekeeping_fn, sconn))) {
3534 DEBUG(0, ("Could not add housekeeping event\n"));
3535 exit(1);
3538 #ifdef CLUSTER_SUPPORT
3540 if (lp_clustering()) {
3542 * We need to tell ctdb about our client's TCP
3543 * connection, so that for failover ctdbd can send
3544 * tickle acks, triggering a reconnection by the
3545 * client.
3548 struct sockaddr_storage srv, clnt;
3550 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3551 NTSTATUS status;
3552 status = smbd_register_ips(sconn, &srv, &clnt);
3553 if (!NT_STATUS_IS_OK(status)) {
3554 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3555 nt_errstr(status)));
3557 } else
3559 DEBUG(0,("Unable to get tcp info for "
3560 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3561 strerror(errno)));
3565 #endif
3567 sconn->nbt.got_session = false;
3569 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3571 sconn->smb1.sessions.done_sesssetup = false;
3572 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3573 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3575 if (!init_dptrs(sconn)) {
3576 exit_server("init_dptrs() failed");
3579 sconn->smb1.fde = event_add_fd(ev_ctx,
3580 sconn,
3581 sconn->sock,
3582 EVENT_FD_READ,
3583 smbd_server_connection_handler,
3584 sconn);
3585 if (!sconn->smb1.fde) {
3586 exit_server("failed to create smbd_server_connection fde");
3589 sconn->conn->local_address = sconn->local_address;
3590 sconn->conn->remote_address = sconn->remote_address;
3591 sconn->conn->remote_hostname = sconn->remote_hostname;
3592 sconn->conn->protocol = PROTOCOL_NONE;
3594 TALLOC_FREE(frame);
3596 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3598 while (True) {
3599 frame = talloc_stackframe_pool(8192);
3601 errno = 0;
3602 if (tevent_loop_once(ev_ctx) == -1) {
3603 if (errno != EINTR) {
3604 DEBUG(3, ("tevent_loop_once failed: %s,"
3605 " exiting\n", strerror(errno) ));
3606 break;
3610 TALLOC_FREE(frame);
3613 exit_server_cleanly(NULL);
3616 bool req_is_in_chain(struct smb_request *req)
3618 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3620 * We're right now handling a subsequent request, so we must
3621 * be in a chain
3623 return true;
3626 if (!is_andx_req(req->cmd)) {
3627 return false;
3630 if (req->wct < 2) {
3632 * Okay, an illegal request, but definitely not chained :-)
3634 return false;
3637 return (CVAL(req->vwv+0, 0) != 0xFF);