lib/util: Remove sys_poll as it is no longer needed
[Samba.git] / source3 / smbd / process.c
blobf295a59f86f85017b80d9cb4ce442bd074d9998a
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"
43 extern bool global_machine_password_needs_changing;
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct timed_event *te;
51 struct smb_perfcount_data pcd;
52 uint32_t seqnum;
53 bool encrypted;
54 bool processed;
55 DATA_BLOB buf;
56 DATA_BLOB private_data;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
60 char *outbuf);
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
66 bool ok;
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 return true;
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
75 return true;
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
83 SMB_F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
86 if (!ok) {
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 return false;
91 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
93 return true;
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
105 bool ok;
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 return true;
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
114 return true;
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
120 SMB_F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
123 if (!ok) {
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 return false;
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
130 return true;
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
143 Send an smb to a fd.
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
151 size_t len = 0;
152 size_t nwritten=0;
153 ssize_t ret;
154 char *buf_out = buffer;
156 smbd_lock_socket(sconn);
158 if (do_signing) {
159 /* Sign the outgoing packet if required. */
160 srv_calculate_sign_mac(sconn, buf_out, seqnum);
163 if (do_encrypt) {
164 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
165 if (!NT_STATUS_IS_OK(status)) {
166 DEBUG(0, ("send_smb: SMB encryption failed "
167 "on outgoing packet! Error %s\n",
168 nt_errstr(status) ));
169 goto out;
173 len = smb_len(buf_out) + 4;
175 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
176 if (ret <= 0) {
178 char addr[INET6_ADDRSTRLEN];
180 * Try and give an error message saying what
181 * client failed.
183 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
184 (int)sys_getpid(), (int)len,
185 get_peer_addr(sconn->sock, addr, sizeof(addr)),
186 (int)ret, strerror(errno) ));
188 srv_free_enc_buffer(sconn, buf_out);
189 goto out;
192 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
193 srv_free_enc_buffer(sconn, buf_out);
194 out:
195 SMB_PERFCOUNT_END(pcd);
197 smbd_unlock_socket(sconn);
198 return true;
201 /*******************************************************************
202 Setup the word count and byte count for a smb message.
203 ********************************************************************/
205 int srv_set_message(char *buf,
206 int num_words,
207 int num_bytes,
208 bool zero)
210 if (zero && (num_words || num_bytes)) {
211 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
213 SCVAL(buf,smb_wct,num_words);
214 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
215 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
216 return (smb_size + num_words*2 + num_bytes);
219 static bool valid_smb_header(struct smbd_server_connection *sconn,
220 const uint8_t *inbuf)
222 if (is_encrypted_packet(sconn, inbuf)) {
223 return true;
226 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
227 * but it just looks weird to call strncmp for this one.
229 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
232 /* Socket functions for smbd packet processing. */
234 static bool valid_packet_size(size_t len)
237 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
238 * of header. Don't print the error if this fits.... JRA.
241 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
242 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
243 (unsigned long)len));
244 return false;
246 return true;
249 static NTSTATUS read_packet_remainder(int fd, char *buffer,
250 unsigned int timeout, ssize_t len)
252 NTSTATUS status;
254 if (len <= 0) {
255 return NT_STATUS_OK;
258 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
259 if (!NT_STATUS_IS_OK(status)) {
260 char addr[INET6_ADDRSTRLEN];
261 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
262 "error = %s.\n",
263 get_peer_addr(fd, addr, sizeof(addr)),
264 nt_errstr(status)));
266 return status;
269 /****************************************************************************
270 Attempt a zerocopy writeX read. We know here that len > smb_size-4
271 ****************************************************************************/
274 * Unfortunately, earlier versions of smbclient/libsmbclient
275 * don't send this "standard" writeX header. I've fixed this
276 * for 3.2 but we'll use the old method with earlier versions.
277 * Windows and CIFSFS at least use this standard size. Not
278 * sure about MacOSX.
281 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
282 (2*14) + /* word count (including bcc) */ \
283 1 /* pad byte */)
285 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
286 const char lenbuf[4],
287 struct smbd_server_connection *sconn,
288 int sock,
289 char **buffer,
290 unsigned int timeout,
291 size_t *p_unread,
292 size_t *len_ret)
294 /* Size of a WRITEX call (+4 byte len). */
295 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
296 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
297 ssize_t toread;
298 NTSTATUS status;
300 memcpy(writeX_header, lenbuf, 4);
302 status = read_fd_with_timeout(
303 sock, writeX_header + 4,
304 STANDARD_WRITE_AND_X_HEADER_SIZE,
305 STANDARD_WRITE_AND_X_HEADER_SIZE,
306 timeout, NULL);
308 if (!NT_STATUS_IS_OK(status)) {
309 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
310 "error = %s.\n",
311 tsocket_address_string(sconn->remote_address,
312 talloc_tos()),
313 nt_errstr(status)));
314 return status;
318 * Ok - now try and see if this is a possible
319 * valid writeX call.
322 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
324 * If the data offset is beyond what
325 * we've read, drain the extra bytes.
327 uint16_t doff = SVAL(writeX_header,smb_vwv11);
328 ssize_t newlen;
330 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
331 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
332 if (drain_socket(sock, drain) != drain) {
333 smb_panic("receive_smb_raw_talloc_partial_read:"
334 " failed to drain pending bytes");
336 } else {
337 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
340 /* Spoof down the length and null out the bcc. */
341 set_message_bcc(writeX_header, 0);
342 newlen = smb_len(writeX_header);
344 /* Copy the header we've written. */
346 *buffer = (char *)talloc_memdup(mem_ctx,
347 writeX_header,
348 sizeof(writeX_header));
350 if (*buffer == NULL) {
351 DEBUG(0, ("Could not allocate inbuf of length %d\n",
352 (int)sizeof(writeX_header)));
353 return NT_STATUS_NO_MEMORY;
356 /* Work out the remaining bytes. */
357 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
358 *len_ret = newlen + 4;
359 return NT_STATUS_OK;
362 if (!valid_packet_size(len)) {
363 return NT_STATUS_INVALID_PARAMETER;
367 * Not a valid writeX call. Just do the standard
368 * talloc and return.
371 *buffer = talloc_array(mem_ctx, char, len+4);
373 if (*buffer == NULL) {
374 DEBUG(0, ("Could not allocate inbuf of length %d\n",
375 (int)len+4));
376 return NT_STATUS_NO_MEMORY;
379 /* Copy in what we already read. */
380 memcpy(*buffer,
381 writeX_header,
382 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
383 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
385 if(toread > 0) {
386 status = read_packet_remainder(
387 sock,
388 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
389 timeout, toread);
391 if (!NT_STATUS_IS_OK(status)) {
392 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
393 nt_errstr(status)));
394 return status;
398 *len_ret = len + 4;
399 return NT_STATUS_OK;
402 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
403 struct smbd_server_connection *sconn,
404 int sock,
405 char **buffer, unsigned int timeout,
406 size_t *p_unread, size_t *plen)
408 char lenbuf[4];
409 size_t len;
410 int min_recv_size = lp_min_receive_file_size();
411 NTSTATUS status;
413 *p_unread = 0;
415 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
416 &len);
417 if (!NT_STATUS_IS_OK(status)) {
418 return status;
421 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
422 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
423 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
424 !srv_is_signing_active(sconn) &&
425 sconn->smb1.echo_handler.trusted_fde == NULL) {
427 return receive_smb_raw_talloc_partial_read(
428 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
429 p_unread, plen);
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * The +4 here can't wrap, we've checked the length above already.
440 *buffer = talloc_array(mem_ctx, char, len+4);
442 if (*buffer == NULL) {
443 DEBUG(0, ("Could not allocate inbuf of length %d\n",
444 (int)len+4));
445 return NT_STATUS_NO_MEMORY;
448 memcpy(*buffer, lenbuf, sizeof(lenbuf));
450 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
451 if (!NT_STATUS_IS_OK(status)) {
452 return status;
455 *plen = len + 4;
456 return NT_STATUS_OK;
459 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
460 struct smbd_server_connection *sconn,
461 int sock,
462 char **buffer, unsigned int timeout,
463 size_t *p_unread, bool *p_encrypted,
464 size_t *p_len,
465 uint32_t *seqnum,
466 bool trusted_channel)
468 size_t len = 0;
469 NTSTATUS status;
471 *p_encrypted = false;
473 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
474 p_unread, &len);
475 if (!NT_STATUS_IS_OK(status)) {
476 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
477 ("receive_smb_raw_talloc failed for client %s "
478 "read error = %s.\n",
479 tsocket_address_string(sconn->remote_address,
480 talloc_tos()),
481 nt_errstr(status)) );
482 return status;
485 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
486 status = srv_decrypt_buffer(sconn, *buffer);
487 if (!NT_STATUS_IS_OK(status)) {
488 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
489 "incoming packet! Error %s\n",
490 nt_errstr(status) ));
491 return status;
493 *p_encrypted = true;
496 /* Check the incoming SMB signature. */
497 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
498 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
499 "incoming packet!\n"));
500 return NT_STATUS_INVALID_NETWORK_RESPONSE;
503 *p_len = len;
504 return NT_STATUS_OK;
508 * Initialize a struct smb_request from an inbuf
511 static bool init_smb_request(struct smb_request *req,
512 struct smbd_server_connection *sconn,
513 const uint8 *inbuf,
514 size_t unread_bytes, bool encrypted,
515 uint32_t seqnum)
517 size_t req_size = smb_len(inbuf) + 4;
518 /* Ensure we have at least smb_size bytes. */
519 if (req_size < smb_size) {
520 DEBUG(0,("init_smb_request: invalid request size %u\n",
521 (unsigned int)req_size ));
522 return false;
524 req->cmd = CVAL(inbuf, smb_com);
525 req->flags2 = SVAL(inbuf, smb_flg2);
526 req->smbpid = SVAL(inbuf, smb_pid);
527 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
528 req->seqnum = seqnum;
529 req->vuid = SVAL(inbuf, smb_uid);
530 req->tid = SVAL(inbuf, smb_tid);
531 req->wct = CVAL(inbuf, smb_wct);
532 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
533 req->buflen = smb_buflen(inbuf);
534 req->buf = (const uint8_t *)smb_buf_const(inbuf);
535 req->unread_bytes = unread_bytes;
536 req->encrypted = encrypted;
537 req->sconn = sconn;
538 req->conn = conn_find(sconn,req->tid);
539 req->chain_fsp = NULL;
540 req->chain_outbuf = NULL;
541 req->done = false;
542 req->smb2req = NULL;
543 smb_init_perfcount_data(&req->pcd);
545 /* Ensure we have at least wct words and 2 bytes of bcc. */
546 if (smb_size + req->wct*2 > req_size) {
547 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
548 (unsigned int)req->wct,
549 (unsigned int)req_size));
550 return false;
552 /* Ensure bcc is correct. */
553 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
554 DEBUG(0,("init_smb_request: invalid bcc number %u "
555 "(wct = %u, size %u)\n",
556 (unsigned int)req->buflen,
557 (unsigned int)req->wct,
558 (unsigned int)req_size));
559 return false;
562 req->outbuf = NULL;
563 return true;
566 static void process_smb(struct smbd_server_connection *conn,
567 uint8_t *inbuf, size_t nread, size_t unread_bytes,
568 uint32_t seqnum, bool encrypted,
569 struct smb_perfcount_data *deferred_pcd);
571 static void smbd_deferred_open_timer(struct event_context *ev,
572 struct timed_event *te,
573 struct timeval _tval,
574 void *private_data)
576 struct pending_message_list *msg = talloc_get_type(private_data,
577 struct pending_message_list);
578 struct smbd_server_connection *sconn = msg->sconn;
579 TALLOC_CTX *mem_ctx = talloc_tos();
580 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
581 uint8_t *inbuf;
583 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
584 msg->buf.length);
585 if (inbuf == NULL) {
586 exit_server("smbd_deferred_open_timer: talloc failed\n");
587 return;
590 /* We leave this message on the queue so the open code can
591 know this is a retry. */
592 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
593 (unsigned long long)mid ));
595 /* Mark the message as processed so this is not
596 * re-processed in error. */
597 msg->processed = true;
599 process_smb(sconn, inbuf,
600 msg->buf.length, 0,
601 msg->seqnum, msg->encrypted, &msg->pcd);
603 /* If it's still there and was processed, remove it. */
604 msg = get_deferred_open_message_smb(sconn, mid);
605 if (msg && msg->processed) {
606 remove_deferred_open_message_smb(sconn, mid);
610 /****************************************************************************
611 Function to push a message onto the tail of a linked list of smb messages ready
612 for processing.
613 ****************************************************************************/
615 static bool push_queued_message(struct smb_request *req,
616 struct timeval request_time,
617 struct timeval end_time,
618 char *private_data, size_t private_len)
620 int msg_len = smb_len(req->inbuf) + 4;
621 struct pending_message_list *msg;
623 msg = talloc_zero(NULL, struct pending_message_list);
625 if(msg == NULL) {
626 DEBUG(0,("push_message: malloc fail (1)\n"));
627 return False;
629 msg->sconn = req->sconn;
631 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
632 if(msg->buf.data == NULL) {
633 DEBUG(0,("push_message: malloc fail (2)\n"));
634 TALLOC_FREE(msg);
635 return False;
638 msg->request_time = request_time;
639 msg->seqnum = req->seqnum;
640 msg->encrypted = req->encrypted;
641 msg->processed = false;
642 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
644 if (private_data) {
645 msg->private_data = data_blob_talloc(msg, private_data,
646 private_len);
647 if (msg->private_data.data == NULL) {
648 DEBUG(0,("push_message: malloc fail (3)\n"));
649 TALLOC_FREE(msg);
650 return False;
654 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
655 msg,
656 end_time,
657 smbd_deferred_open_timer,
658 msg);
659 if (!msg->te) {
660 DEBUG(0,("push_message: event_add_timed failed\n"));
661 TALLOC_FREE(msg);
662 return false;
665 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
666 struct pending_message_list *);
668 DEBUG(10,("push_message: pushed message length %u on "
669 "deferred_open_queue\n", (unsigned int)msg_len));
671 return True;
674 /****************************************************************************
675 Function to delete a sharing violation open message by mid.
676 ****************************************************************************/
678 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
679 uint64_t mid)
681 struct pending_message_list *pml;
683 if (sconn->using_smb2) {
684 remove_deferred_open_message_smb2(sconn, mid);
685 return;
688 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
689 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
690 DEBUG(10,("remove_deferred_open_message_smb: "
691 "deleting mid %llu len %u\n",
692 (unsigned long long)mid,
693 (unsigned int)pml->buf.length ));
694 DLIST_REMOVE(sconn->deferred_open_queue, pml);
695 TALLOC_FREE(pml);
696 return;
701 /****************************************************************************
702 Move a sharing violation open retry message to the front of the list and
703 schedule it for immediate processing.
704 ****************************************************************************/
706 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
707 uint64_t mid)
709 struct pending_message_list *pml;
710 int i = 0;
712 if (sconn->using_smb2) {
713 schedule_deferred_open_message_smb2(sconn, mid);
714 return;
717 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
718 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
720 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
721 "msg_mid = %llu\n",
722 i++,
723 (unsigned long long)msg_mid ));
725 if (mid == msg_mid) {
726 struct timed_event *te;
728 if (pml->processed) {
729 /* A processed message should not be
730 * rescheduled. */
731 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
732 "message mid %llu was already processed\n",
733 (unsigned long long)msg_mid ));
734 continue;
737 DEBUG(10,("schedule_deferred_open_message_smb: "
738 "scheduling mid %llu\n",
739 (unsigned long long)mid ));
741 te = tevent_add_timer(pml->sconn->ev_ctx,
742 pml,
743 timeval_zero(),
744 smbd_deferred_open_timer,
745 pml);
746 if (!te) {
747 DEBUG(10,("schedule_deferred_open_message_smb: "
748 "event_add_timed() failed, "
749 "skipping mid %llu\n",
750 (unsigned long long)msg_mid ));
753 TALLOC_FREE(pml->te);
754 pml->te = te;
755 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
756 return;
760 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
761 "find message mid %llu\n",
762 (unsigned long long)mid ));
765 /****************************************************************************
766 Return true if this mid is on the deferred queue and was not yet processed.
767 ****************************************************************************/
769 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
771 struct pending_message_list *pml;
773 if (sconn->using_smb2) {
774 return open_was_deferred_smb2(sconn, mid);
777 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
778 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
779 return True;
782 return False;
785 /****************************************************************************
786 Return the message queued by this mid.
787 ****************************************************************************/
789 static struct pending_message_list *get_deferred_open_message_smb(
790 struct smbd_server_connection *sconn, uint64_t mid)
792 struct pending_message_list *pml;
794 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
795 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
796 return pml;
799 return NULL;
802 /****************************************************************************
803 Get the state data queued by this mid.
804 ****************************************************************************/
806 bool get_deferred_open_message_state(struct smb_request *smbreq,
807 struct timeval *p_request_time,
808 void **pp_state)
810 struct pending_message_list *pml;
812 if (smbreq->sconn->using_smb2) {
813 return get_deferred_open_message_state_smb2(smbreq->smb2req,
814 p_request_time,
815 pp_state);
818 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
819 if (!pml) {
820 return false;
822 if (p_request_time) {
823 *p_request_time = pml->request_time;
825 if (pp_state) {
826 *pp_state = (void *)pml->private_data.data;
828 return true;
831 /****************************************************************************
832 Function to push a deferred open smb message onto a linked list of local smb
833 messages ready for processing.
834 ****************************************************************************/
836 bool push_deferred_open_message_smb(struct smb_request *req,
837 struct timeval request_time,
838 struct timeval timeout,
839 struct file_id id,
840 char *private_data, size_t priv_len)
842 struct timeval end_time;
844 if (req->smb2req) {
845 return push_deferred_open_message_smb2(req->smb2req,
846 request_time,
847 timeout,
849 private_data,
850 priv_len);
853 if (req->unread_bytes) {
854 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
855 "unread_bytes = %u\n",
856 (unsigned int)req->unread_bytes ));
857 smb_panic("push_deferred_open_message_smb: "
858 "logic error unread_bytes != 0" );
861 end_time = timeval_sum(&request_time, &timeout);
863 DEBUG(10,("push_deferred_open_message_smb: pushing message "
864 "len %u mid %llu timeout time [%u.%06u]\n",
865 (unsigned int) smb_len(req->inbuf)+4,
866 (unsigned long long)req->mid,
867 (unsigned int)end_time.tv_sec,
868 (unsigned int)end_time.tv_usec));
870 return push_queued_message(req, request_time, end_time,
871 private_data, priv_len);
874 static void smbd_sig_term_handler(struct tevent_context *ev,
875 struct tevent_signal *se,
876 int signum,
877 int count,
878 void *siginfo,
879 void *private_data)
881 exit_server_cleanly("termination signal");
884 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
886 struct tevent_signal *se;
888 se = tevent_add_signal(sconn->ev_ctx,
889 sconn,
890 SIGTERM, 0,
891 smbd_sig_term_handler,
892 sconn);
893 if (!se) {
894 exit_server("failed to setup SIGTERM handler");
898 static void smbd_sig_hup_handler(struct tevent_context *ev,
899 struct tevent_signal *se,
900 int signum,
901 int count,
902 void *siginfo,
903 void *private_data)
905 struct smbd_server_connection *sconn =
906 talloc_get_type_abort(private_data,
907 struct smbd_server_connection);
909 change_to_root_user();
910 DEBUG(1,("Reloading services after SIGHUP\n"));
911 reload_services(sconn, conn_snum_used, false);
914 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
916 struct tevent_signal *se;
918 se = tevent_add_signal(sconn->ev_ctx,
919 sconn,
920 SIGHUP, 0,
921 smbd_sig_hup_handler,
922 sconn);
923 if (!se) {
924 exit_server("failed to setup SIGHUP handler");
928 static void smbd_conf_updated(struct messaging_context *msg,
929 void *private_data,
930 uint32_t msg_type,
931 struct server_id server_id,
932 DATA_BLOB *data)
934 struct smbd_server_connection *sconn =
935 talloc_get_type_abort(private_data,
936 struct smbd_server_connection);
938 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
939 "updated. Reloading.\n"));
940 change_to_root_user();
941 reload_services(sconn, conn_snum_used, false);
944 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
945 struct smbd_server_connection *conn)
947 int timeout;
948 int num_pfds = 0;
949 int ret;
950 bool retry;
952 timeout = SMBD_SELECT_TIMEOUT * 1000;
955 * Are there any timed events waiting ? If so, ensure we don't
956 * select for longer than it would take to wait for them.
959 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
961 /* Process a signal and timed events now... */
962 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
963 return NT_STATUS_RETRY;
967 int sav;
968 START_PROFILE(smbd_idle);
970 ret = poll(conn->pfds, num_pfds, timeout);
971 sav = errno;
973 END_PROFILE(smbd_idle);
974 errno = sav;
977 if (ret == -1) {
978 if (errno == EINTR) {
979 return NT_STATUS_RETRY;
981 return map_nt_error_from_unix(errno);
984 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
985 if (retry) {
986 return NT_STATUS_RETRY;
989 /* Did we timeout ? */
990 if (ret == 0) {
991 return NT_STATUS_RETRY;
994 /* should not be reached */
995 return NT_STATUS_INTERNAL_ERROR;
999 * Only allow 5 outstanding trans requests. We're allocating memory, so
1000 * prevent a DoS.
1003 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1005 int count = 0;
1006 for (; list != NULL; list = list->next) {
1008 if (list->mid == mid) {
1009 return NT_STATUS_INVALID_PARAMETER;
1012 count += 1;
1014 if (count > 5) {
1015 return NT_STATUS_INSUFFICIENT_RESOURCES;
1018 return NT_STATUS_OK;
1022 These flags determine some of the permissions required to do an operation
1024 Note that I don't set NEED_WRITE on some write operations because they
1025 are used by some brain-dead clients when printing, and I don't want to
1026 force write permissions on print services.
1028 #define AS_USER (1<<0)
1029 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1030 #define TIME_INIT (1<<2)
1031 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1032 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1033 #define DO_CHDIR (1<<6)
1036 define a list of possible SMB messages and their corresponding
1037 functions. Any message that has a NULL function is unimplemented -
1038 please feel free to contribute implementations!
1040 static const struct smb_message_struct {
1041 const char *name;
1042 void (*fn)(struct smb_request *req);
1043 int flags;
1044 } smb_messages[256] = {
1046 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1047 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1048 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1049 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1050 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1051 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1052 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1053 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1054 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1055 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1056 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1057 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1058 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1059 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1060 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1061 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1062 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1063 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1064 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1065 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1066 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1067 /* 0x15 */ { NULL, NULL, 0 },
1068 /* 0x16 */ { NULL, NULL, 0 },
1069 /* 0x17 */ { NULL, NULL, 0 },
1070 /* 0x18 */ { NULL, NULL, 0 },
1071 /* 0x19 */ { NULL, NULL, 0 },
1072 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1073 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1074 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1075 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1076 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1077 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1078 /* 0x20 */ { "SMBwritec", NULL,0},
1079 /* 0x21 */ { NULL, NULL, 0 },
1080 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1081 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1082 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1083 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1084 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1085 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1086 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1087 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1088 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1089 /* 0x2b */ { "SMBecho",reply_echo,0},
1090 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1091 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1092 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1093 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1094 /* 0x30 */ { NULL, NULL, 0 },
1095 /* 0x31 */ { NULL, NULL, 0 },
1096 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1097 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1098 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1099 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1100 /* 0x36 */ { NULL, NULL, 0 },
1101 /* 0x37 */ { NULL, NULL, 0 },
1102 /* 0x38 */ { NULL, NULL, 0 },
1103 /* 0x39 */ { NULL, NULL, 0 },
1104 /* 0x3a */ { NULL, NULL, 0 },
1105 /* 0x3b */ { NULL, NULL, 0 },
1106 /* 0x3c */ { NULL, NULL, 0 },
1107 /* 0x3d */ { NULL, NULL, 0 },
1108 /* 0x3e */ { NULL, NULL, 0 },
1109 /* 0x3f */ { NULL, NULL, 0 },
1110 /* 0x40 */ { NULL, NULL, 0 },
1111 /* 0x41 */ { NULL, NULL, 0 },
1112 /* 0x42 */ { NULL, NULL, 0 },
1113 /* 0x43 */ { NULL, NULL, 0 },
1114 /* 0x44 */ { NULL, NULL, 0 },
1115 /* 0x45 */ { NULL, NULL, 0 },
1116 /* 0x46 */ { NULL, NULL, 0 },
1117 /* 0x47 */ { NULL, NULL, 0 },
1118 /* 0x48 */ { NULL, NULL, 0 },
1119 /* 0x49 */ { NULL, NULL, 0 },
1120 /* 0x4a */ { NULL, NULL, 0 },
1121 /* 0x4b */ { NULL, NULL, 0 },
1122 /* 0x4c */ { NULL, NULL, 0 },
1123 /* 0x4d */ { NULL, NULL, 0 },
1124 /* 0x4e */ { NULL, NULL, 0 },
1125 /* 0x4f */ { NULL, NULL, 0 },
1126 /* 0x50 */ { NULL, NULL, 0 },
1127 /* 0x51 */ { NULL, NULL, 0 },
1128 /* 0x52 */ { NULL, NULL, 0 },
1129 /* 0x53 */ { NULL, NULL, 0 },
1130 /* 0x54 */ { NULL, NULL, 0 },
1131 /* 0x55 */ { NULL, NULL, 0 },
1132 /* 0x56 */ { NULL, NULL, 0 },
1133 /* 0x57 */ { NULL, NULL, 0 },
1134 /* 0x58 */ { NULL, NULL, 0 },
1135 /* 0x59 */ { NULL, NULL, 0 },
1136 /* 0x5a */ { NULL, NULL, 0 },
1137 /* 0x5b */ { NULL, NULL, 0 },
1138 /* 0x5c */ { NULL, NULL, 0 },
1139 /* 0x5d */ { NULL, NULL, 0 },
1140 /* 0x5e */ { NULL, NULL, 0 },
1141 /* 0x5f */ { NULL, NULL, 0 },
1142 /* 0x60 */ { NULL, NULL, 0 },
1143 /* 0x61 */ { NULL, NULL, 0 },
1144 /* 0x62 */ { NULL, NULL, 0 },
1145 /* 0x63 */ { NULL, NULL, 0 },
1146 /* 0x64 */ { NULL, NULL, 0 },
1147 /* 0x65 */ { NULL, NULL, 0 },
1148 /* 0x66 */ { NULL, NULL, 0 },
1149 /* 0x67 */ { NULL, NULL, 0 },
1150 /* 0x68 */ { NULL, NULL, 0 },
1151 /* 0x69 */ { NULL, NULL, 0 },
1152 /* 0x6a */ { NULL, NULL, 0 },
1153 /* 0x6b */ { NULL, NULL, 0 },
1154 /* 0x6c */ { NULL, NULL, 0 },
1155 /* 0x6d */ { NULL, NULL, 0 },
1156 /* 0x6e */ { NULL, NULL, 0 },
1157 /* 0x6f */ { NULL, NULL, 0 },
1158 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1159 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1160 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1161 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1162 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1163 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1164 /* 0x76 */ { NULL, NULL, 0 },
1165 /* 0x77 */ { NULL, NULL, 0 },
1166 /* 0x78 */ { NULL, NULL, 0 },
1167 /* 0x79 */ { NULL, NULL, 0 },
1168 /* 0x7a */ { NULL, NULL, 0 },
1169 /* 0x7b */ { NULL, NULL, 0 },
1170 /* 0x7c */ { NULL, NULL, 0 },
1171 /* 0x7d */ { NULL, NULL, 0 },
1172 /* 0x7e */ { NULL, NULL, 0 },
1173 /* 0x7f */ { NULL, NULL, 0 },
1174 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1175 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1176 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1177 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1178 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1179 /* 0x85 */ { NULL, NULL, 0 },
1180 /* 0x86 */ { NULL, NULL, 0 },
1181 /* 0x87 */ { NULL, NULL, 0 },
1182 /* 0x88 */ { NULL, NULL, 0 },
1183 /* 0x89 */ { NULL, NULL, 0 },
1184 /* 0x8a */ { NULL, NULL, 0 },
1185 /* 0x8b */ { NULL, NULL, 0 },
1186 /* 0x8c */ { NULL, NULL, 0 },
1187 /* 0x8d */ { NULL, NULL, 0 },
1188 /* 0x8e */ { NULL, NULL, 0 },
1189 /* 0x8f */ { NULL, NULL, 0 },
1190 /* 0x90 */ { NULL, NULL, 0 },
1191 /* 0x91 */ { NULL, NULL, 0 },
1192 /* 0x92 */ { NULL, NULL, 0 },
1193 /* 0x93 */ { NULL, NULL, 0 },
1194 /* 0x94 */ { NULL, NULL, 0 },
1195 /* 0x95 */ { NULL, NULL, 0 },
1196 /* 0x96 */ { NULL, NULL, 0 },
1197 /* 0x97 */ { NULL, NULL, 0 },
1198 /* 0x98 */ { NULL, NULL, 0 },
1199 /* 0x99 */ { NULL, NULL, 0 },
1200 /* 0x9a */ { NULL, NULL, 0 },
1201 /* 0x9b */ { NULL, NULL, 0 },
1202 /* 0x9c */ { NULL, NULL, 0 },
1203 /* 0x9d */ { NULL, NULL, 0 },
1204 /* 0x9e */ { NULL, NULL, 0 },
1205 /* 0x9f */ { NULL, NULL, 0 },
1206 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1207 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1208 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1209 /* 0xa3 */ { NULL, NULL, 0 },
1210 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1211 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1212 /* 0xa6 */ { NULL, NULL, 0 },
1213 /* 0xa7 */ { NULL, NULL, 0 },
1214 /* 0xa8 */ { NULL, NULL, 0 },
1215 /* 0xa9 */ { NULL, NULL, 0 },
1216 /* 0xaa */ { NULL, NULL, 0 },
1217 /* 0xab */ { NULL, NULL, 0 },
1218 /* 0xac */ { NULL, NULL, 0 },
1219 /* 0xad */ { NULL, NULL, 0 },
1220 /* 0xae */ { NULL, NULL, 0 },
1221 /* 0xaf */ { NULL, NULL, 0 },
1222 /* 0xb0 */ { NULL, NULL, 0 },
1223 /* 0xb1 */ { NULL, NULL, 0 },
1224 /* 0xb2 */ { NULL, NULL, 0 },
1225 /* 0xb3 */ { NULL, NULL, 0 },
1226 /* 0xb4 */ { NULL, NULL, 0 },
1227 /* 0xb5 */ { NULL, NULL, 0 },
1228 /* 0xb6 */ { NULL, NULL, 0 },
1229 /* 0xb7 */ { NULL, NULL, 0 },
1230 /* 0xb8 */ { NULL, NULL, 0 },
1231 /* 0xb9 */ { NULL, NULL, 0 },
1232 /* 0xba */ { NULL, NULL, 0 },
1233 /* 0xbb */ { NULL, NULL, 0 },
1234 /* 0xbc */ { NULL, NULL, 0 },
1235 /* 0xbd */ { NULL, NULL, 0 },
1236 /* 0xbe */ { NULL, NULL, 0 },
1237 /* 0xbf */ { NULL, NULL, 0 },
1238 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1239 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1240 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1241 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1242 /* 0xc4 */ { NULL, NULL, 0 },
1243 /* 0xc5 */ { NULL, NULL, 0 },
1244 /* 0xc6 */ { NULL, NULL, 0 },
1245 /* 0xc7 */ { NULL, NULL, 0 },
1246 /* 0xc8 */ { NULL, NULL, 0 },
1247 /* 0xc9 */ { NULL, NULL, 0 },
1248 /* 0xca */ { NULL, NULL, 0 },
1249 /* 0xcb */ { NULL, NULL, 0 },
1250 /* 0xcc */ { NULL, NULL, 0 },
1251 /* 0xcd */ { NULL, NULL, 0 },
1252 /* 0xce */ { NULL, NULL, 0 },
1253 /* 0xcf */ { NULL, NULL, 0 },
1254 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1255 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1256 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1257 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1258 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1259 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1260 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1261 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1262 /* 0xd8 */ { NULL, NULL, 0 },
1263 /* 0xd9 */ { NULL, NULL, 0 },
1264 /* 0xda */ { NULL, NULL, 0 },
1265 /* 0xdb */ { NULL, NULL, 0 },
1266 /* 0xdc */ { NULL, NULL, 0 },
1267 /* 0xdd */ { NULL, NULL, 0 },
1268 /* 0xde */ { NULL, NULL, 0 },
1269 /* 0xdf */ { NULL, NULL, 0 },
1270 /* 0xe0 */ { NULL, NULL, 0 },
1271 /* 0xe1 */ { NULL, NULL, 0 },
1272 /* 0xe2 */ { NULL, NULL, 0 },
1273 /* 0xe3 */ { NULL, NULL, 0 },
1274 /* 0xe4 */ { NULL, NULL, 0 },
1275 /* 0xe5 */ { NULL, NULL, 0 },
1276 /* 0xe6 */ { NULL, NULL, 0 },
1277 /* 0xe7 */ { NULL, NULL, 0 },
1278 /* 0xe8 */ { NULL, NULL, 0 },
1279 /* 0xe9 */ { NULL, NULL, 0 },
1280 /* 0xea */ { NULL, NULL, 0 },
1281 /* 0xeb */ { NULL, NULL, 0 },
1282 /* 0xec */ { NULL, NULL, 0 },
1283 /* 0xed */ { NULL, NULL, 0 },
1284 /* 0xee */ { NULL, NULL, 0 },
1285 /* 0xef */ { NULL, NULL, 0 },
1286 /* 0xf0 */ { NULL, NULL, 0 },
1287 /* 0xf1 */ { NULL, NULL, 0 },
1288 /* 0xf2 */ { NULL, NULL, 0 },
1289 /* 0xf3 */ { NULL, NULL, 0 },
1290 /* 0xf4 */ { NULL, NULL, 0 },
1291 /* 0xf5 */ { NULL, NULL, 0 },
1292 /* 0xf6 */ { NULL, NULL, 0 },
1293 /* 0xf7 */ { NULL, NULL, 0 },
1294 /* 0xf8 */ { NULL, NULL, 0 },
1295 /* 0xf9 */ { NULL, NULL, 0 },
1296 /* 0xfa */ { NULL, NULL, 0 },
1297 /* 0xfb */ { NULL, NULL, 0 },
1298 /* 0xfc */ { NULL, NULL, 0 },
1299 /* 0xfd */ { NULL, NULL, 0 },
1300 /* 0xfe */ { NULL, NULL, 0 },
1301 /* 0xff */ { NULL, NULL, 0 }
1305 /*******************************************************************
1306 allocate and initialize a reply packet
1307 ********************************************************************/
1309 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1310 const char *inbuf, char **outbuf, uint8_t num_words,
1311 uint32_t num_bytes)
1314 * Protect against integer wrap
1316 if ((num_bytes > 0xffffff)
1317 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1318 char *msg;
1319 if (asprintf(&msg, "num_bytes too large: %u",
1320 (unsigned)num_bytes) == -1) {
1321 msg = discard_const_p(char, "num_bytes too large");
1323 smb_panic(msg);
1326 *outbuf = talloc_array(mem_ctx, char,
1327 smb_size + num_words*2 + num_bytes);
1328 if (*outbuf == NULL) {
1329 return false;
1332 construct_reply_common(req, inbuf, *outbuf);
1333 srv_set_message(*outbuf, num_words, num_bytes, false);
1335 * Zero out the word area, the caller has to take care of the bcc area
1336 * himself
1338 if (num_words != 0) {
1339 memset(*outbuf + smb_vwv0, 0, num_words*2);
1342 return true;
1345 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1347 char *outbuf;
1348 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1349 num_bytes)) {
1350 smb_panic("could not allocate output buffer\n");
1352 req->outbuf = (uint8_t *)outbuf;
1356 /*******************************************************************
1357 Dump a packet to a file.
1358 ********************************************************************/
1360 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1362 int fd, i;
1363 char *fname = NULL;
1364 if (DEBUGLEVEL < 50) {
1365 return;
1368 if (len < 4) len = smb_len(data)+4;
1369 for (i=1;i<100;i++) {
1370 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1371 type ? "req" : "resp") == -1) {
1372 return;
1374 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1375 if (fd != -1 || errno != EEXIST) break;
1377 if (fd != -1) {
1378 ssize_t ret = write(fd, data, len);
1379 if (ret != len)
1380 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1381 close(fd);
1382 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1384 SAFE_FREE(fname);
1387 /****************************************************************************
1388 Prepare everything for calling the actual request function, and potentially
1389 call the request function via the "new" interface.
1391 Return False if the "legacy" function needs to be called, everything is
1392 prepared.
1394 Return True if we're done.
1396 I know this API sucks, but it is the one with the least code change I could
1397 find.
1398 ****************************************************************************/
1400 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1402 int flags;
1403 uint16 session_tag;
1404 connection_struct *conn = NULL;
1405 struct smbd_server_connection *sconn = req->sconn;
1406 char *raddr;
1408 errno = 0;
1410 if (smb_messages[type].fn == NULL) {
1411 DEBUG(0,("Unknown message type %d!\n",type));
1412 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1413 reply_unknown_new(req, type);
1414 return NULL;
1417 flags = smb_messages[type].flags;
1419 /* In share mode security we must ignore the vuid. */
1420 session_tag = (lp_security() == SEC_SHARE)
1421 ? UID_FIELD_INVALID : req->vuid;
1422 conn = req->conn;
1424 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1425 (int)sys_getpid(), (unsigned long)conn));
1427 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1429 /* Ensure this value is replaced in the incoming packet. */
1430 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1433 * Ensure the correct username is in current_user_info. This is a
1434 * really ugly bugfix for problems with multiple session_setup_and_X's
1435 * being done and allowing %U and %G substitutions to work correctly.
1436 * There is a reason this code is done here, don't move it unless you
1437 * know what you're doing... :-).
1438 * JRA.
1441 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1442 user_struct *vuser = NULL;
1444 sconn->smb1.sessions.last_session_tag = session_tag;
1445 if(session_tag != UID_FIELD_INVALID) {
1446 vuser = get_valid_user_struct(sconn, session_tag);
1447 if (vuser) {
1448 set_current_user_info(
1449 vuser->session_info->unix_info->sanitized_username,
1450 vuser->session_info->unix_info->unix_name,
1451 vuser->session_info->info->domain_name);
1456 /* Does this call need to be run as the connected user? */
1457 if (flags & AS_USER) {
1459 /* Does this call need a valid tree connection? */
1460 if (!conn) {
1462 * Amazingly, the error code depends on the command
1463 * (from Samba4).
1465 if (type == SMBntcreateX) {
1466 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1467 } else {
1468 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1470 return NULL;
1473 if (!change_to_user(conn,session_tag)) {
1474 DEBUG(0, ("Error: Could not change to user. Removing "
1475 "deferred open, mid=%llu.\n",
1476 (unsigned long long)req->mid));
1477 reply_force_doserror(req, ERRSRV, ERRbaduid);
1478 return conn;
1481 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1483 /* Does it need write permission? */
1484 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1485 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1486 return conn;
1489 /* IPC services are limited */
1490 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1491 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1492 return conn;
1494 } else {
1495 /* This call needs to be run as root */
1496 change_to_root_user();
1499 /* load service specific parameters */
1500 if (conn) {
1501 if (req->encrypted) {
1502 conn->encrypted_tid = true;
1503 /* encrypted required from now on. */
1504 conn->encrypt_level = Required;
1505 } else if (ENCRYPTION_REQUIRED(conn)) {
1506 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1507 exit_server_cleanly("encryption required "
1508 "on connection");
1509 return conn;
1513 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1514 (flags & (AS_USER|DO_CHDIR)
1515 ?True:False))) {
1516 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1517 return conn;
1519 conn->num_smb_operations++;
1522 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1523 talloc_tos());
1524 if (raddr == NULL) {
1525 reply_nterror(req, NT_STATUS_NO_MEMORY);
1526 return conn;
1529 /* does this protocol need to be run as guest? */
1530 if ((flags & AS_GUEST)
1531 && (!change_to_guest() ||
1532 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1533 sconn->remote_hostname,
1534 raddr))) {
1535 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1536 return conn;
1539 smb_messages[type].fn(req);
1540 return req->conn;
1543 /****************************************************************************
1544 Construct a reply to the incoming packet.
1545 ****************************************************************************/
1547 static void construct_reply(struct smbd_server_connection *sconn,
1548 char *inbuf, int size, size_t unread_bytes,
1549 uint32_t seqnum, bool encrypted,
1550 struct smb_perfcount_data *deferred_pcd)
1552 connection_struct *conn;
1553 struct smb_request *req;
1555 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1556 smb_panic("could not allocate smb_request");
1559 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1560 encrypted, seqnum)) {
1561 exit_server_cleanly("Invalid SMB request");
1564 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1566 /* we popped this message off the queue - keep original perf data */
1567 if (deferred_pcd)
1568 req->pcd = *deferred_pcd;
1569 else {
1570 SMB_PERFCOUNT_START(&req->pcd);
1571 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1572 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1575 conn = switch_message(req->cmd, req, size);
1577 if (req->unread_bytes) {
1578 /* writeX failed. drain socket. */
1579 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1580 req->unread_bytes) {
1581 smb_panic("failed to drain pending bytes");
1583 req->unread_bytes = 0;
1586 if (req->done) {
1587 TALLOC_FREE(req);
1588 return;
1591 if (req->outbuf == NULL) {
1592 return;
1595 if (CVAL(req->outbuf,0) == 0) {
1596 show_msg((char *)req->outbuf);
1599 if (!srv_send_smb(req->sconn,
1600 (char *)req->outbuf,
1601 true, req->seqnum+1,
1602 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1603 &req->pcd)) {
1604 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1607 TALLOC_FREE(req);
1609 return;
1612 /****************************************************************************
1613 Process an smb from the client
1614 ****************************************************************************/
1615 static void process_smb(struct smbd_server_connection *sconn,
1616 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1617 uint32_t seqnum, bool encrypted,
1618 struct smb_perfcount_data *deferred_pcd)
1620 int msg_type = CVAL(inbuf,0);
1622 DO_PROFILE_INC(smb_count);
1624 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1625 smb_len(inbuf) ) );
1626 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1627 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1629 if (msg_type != NBSSmessage) {
1631 * NetBIOS session request, keepalive, etc.
1633 reply_special(sconn, (char *)inbuf, nread);
1634 goto done;
1637 if (sconn->using_smb2) {
1638 /* At this point we're not really using smb2,
1639 * we make the decision here.. */
1640 if (smbd_is_smb2_header(inbuf, nread)) {
1641 smbd_smb2_first_negprot(sconn, inbuf, nread);
1642 return;
1643 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1644 && CVAL(inbuf, smb_com) != 0x72) {
1645 /* This is a non-negprot SMB1 packet.
1646 Disable SMB2 from now on. */
1647 sconn->using_smb2 = false;
1651 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1652 * so subtract 4 from it. */
1653 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1654 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1655 smb_len(inbuf)));
1657 /* special magic for immediate exit */
1658 if ((nread == 9) &&
1659 (IVAL(inbuf, 4) == 0x74697865) &&
1660 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1661 uint8_t exitcode = CVAL(inbuf, 8);
1662 DEBUG(1, ("Exiting immediately with code %d\n",
1663 (int)exitcode));
1664 exit(exitcode);
1667 exit_server_cleanly("Non-SMB packet");
1670 show_msg((char *)inbuf);
1672 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1673 encrypted, deferred_pcd);
1674 sconn->trans_num++;
1676 done:
1677 sconn->num_requests++;
1679 /* The timeout_processing function isn't run nearly
1680 often enough to implement 'max log size' without
1681 overrunning the size of the file by many megabytes.
1682 This is especially true if we are running at debug
1683 level 10. Checking every 50 SMBs is a nice
1684 tradeoff of performance vs log file size overrun. */
1686 if ((sconn->num_requests % 50) == 0 &&
1687 need_to_check_log_size()) {
1688 change_to_root_user();
1689 check_log_size();
1693 /****************************************************************************
1694 Return a string containing the function name of a SMB command.
1695 ****************************************************************************/
1697 const char *smb_fn_name(int type)
1699 const char *unknown_name = "SMBunknown";
1701 if (smb_messages[type].name == NULL)
1702 return(unknown_name);
1704 return(smb_messages[type].name);
1707 /****************************************************************************
1708 Helper functions for contruct_reply.
1709 ****************************************************************************/
1711 void add_to_common_flags2(uint32 v)
1713 common_flags2 |= v;
1716 void remove_from_common_flags2(uint32 v)
1718 common_flags2 &= ~v;
1721 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1722 char *outbuf)
1724 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1725 uint16_t out_flags2 = common_flags2;
1727 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1728 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1729 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1731 srv_set_message(outbuf,0,0,false);
1733 SCVAL(outbuf, smb_com, req->cmd);
1734 SIVAL(outbuf,smb_rcls,0);
1735 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1736 SSVAL(outbuf,smb_flg2, out_flags2);
1737 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1738 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1740 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1741 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1742 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1743 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1746 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1748 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1752 * How many bytes have we already accumulated up to the current wct field
1753 * offset?
1756 size_t req_wct_ofs(struct smb_request *req)
1758 size_t buf_size;
1760 if (req->chain_outbuf == NULL) {
1761 return smb_wct - 4;
1763 buf_size = talloc_get_size(req->chain_outbuf);
1764 if ((buf_size % 4) != 0) {
1765 buf_size += (4 - (buf_size % 4));
1767 return buf_size - 4;
1771 * Hack around reply_nterror & friends not being aware of chained requests,
1772 * generating illegal (i.e. wct==0) chain replies.
1775 static void fixup_chain_error_packet(struct smb_request *req)
1777 uint8_t *outbuf = req->outbuf;
1778 req->outbuf = NULL;
1779 reply_outbuf(req, 2, 0);
1780 memcpy(req->outbuf, outbuf, smb_wct);
1781 TALLOC_FREE(outbuf);
1782 SCVAL(req->outbuf, smb_vwv0, 0xff);
1786 * @brief Find the smb_cmd offset of the last command pushed
1787 * @param[in] buf The buffer we're building up
1788 * @retval Where can we put our next andx cmd?
1790 * While chaining requests, the "next" request we're looking at needs to put
1791 * its SMB_Command before the data the previous request already built up added
1792 * to the chain. Find the offset to the place where we have to put our cmd.
1795 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1797 uint8_t cmd;
1798 size_t ofs;
1800 cmd = CVAL(buf, smb_com);
1802 SMB_ASSERT(is_andx_req(cmd));
1804 ofs = smb_vwv0;
1806 while (CVAL(buf, ofs) != 0xff) {
1808 if (!is_andx_req(CVAL(buf, ofs))) {
1809 return false;
1813 * ofs is from start of smb header, so add the 4 length
1814 * bytes. The next cmd is right after the wct field.
1816 ofs = SVAL(buf, ofs+2) + 4 + 1;
1818 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1821 *pofs = ofs;
1822 return true;
1826 * @brief Do the smb chaining at a buffer level
1827 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1828 * @param[in] smb_command The command that we want to issue
1829 * @param[in] wct How many words?
1830 * @param[in] vwv The words, already in network order
1831 * @param[in] bytes_alignment How shall we align "bytes"?
1832 * @param[in] num_bytes How many bytes?
1833 * @param[in] bytes The data the request ships
1835 * smb_splice_chain() adds the vwv and bytes to the request already present in
1836 * *poutbuf.
1839 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1840 uint8_t wct, const uint16_t *vwv,
1841 size_t bytes_alignment,
1842 uint32_t num_bytes, const uint8_t *bytes)
1844 uint8_t *outbuf;
1845 size_t old_size, new_size;
1846 size_t ofs;
1847 size_t chain_padding = 0;
1848 size_t bytes_padding = 0;
1849 bool first_request;
1851 old_size = talloc_get_size(*poutbuf);
1854 * old_size == smb_wct means we're pushing the first request in for
1855 * libsmb/
1858 first_request = (old_size == smb_wct);
1860 if (!first_request && ((old_size % 4) != 0)) {
1862 * Align the wct field of subsequent requests to a 4-byte
1863 * boundary
1865 chain_padding = 4 - (old_size % 4);
1869 * After the old request comes the new wct field (1 byte), the vwv's
1870 * and the num_bytes field. After at we might need to align the bytes
1871 * given to us to "bytes_alignment", increasing the num_bytes value.
1874 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1876 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1877 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1880 new_size += bytes_padding + num_bytes;
1882 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1883 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1884 (unsigned)new_size));
1885 return false;
1888 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1889 if (outbuf == NULL) {
1890 DEBUG(0, ("talloc failed\n"));
1891 return false;
1893 *poutbuf = outbuf;
1895 if (first_request) {
1896 SCVAL(outbuf, smb_com, smb_command);
1897 } else {
1898 size_t andx_cmd_ofs;
1900 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1901 DEBUG(1, ("invalid command chain\n"));
1902 *poutbuf = talloc_realloc(
1903 NULL, *poutbuf, uint8_t, old_size);
1904 return false;
1907 if (chain_padding != 0) {
1908 memset(outbuf + old_size, 0, chain_padding);
1909 old_size += chain_padding;
1912 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1913 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1916 ofs = old_size;
1919 * Push the chained request:
1921 * wct field
1924 SCVAL(outbuf, ofs, wct);
1925 ofs += 1;
1928 * vwv array
1931 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1932 ofs += sizeof(uint16_t) * wct;
1935 * bcc (byte count)
1938 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1939 ofs += sizeof(uint16_t);
1942 * padding
1945 if (bytes_padding != 0) {
1946 memset(outbuf + ofs, 0, bytes_padding);
1947 ofs += bytes_padding;
1951 * The bytes field
1954 memcpy(outbuf + ofs, bytes, num_bytes);
1956 return true;
1959 /****************************************************************************
1960 Construct a chained reply and add it to the already made reply
1961 ****************************************************************************/
1963 void chain_reply(struct smb_request *req)
1965 size_t smblen = smb_len(req->inbuf);
1966 size_t already_used, length_needed;
1967 uint8_t chain_cmd;
1968 uint32_t chain_offset; /* uint32_t to avoid overflow */
1970 uint8_t wct;
1971 const uint16_t *vwv;
1972 uint16_t buflen;
1973 const uint8_t *buf;
1975 if (IVAL(req->outbuf, smb_rcls) != 0) {
1976 fixup_chain_error_packet(req);
1980 * Any of the AndX requests and replies have at least a wct of
1981 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1982 * beginning of the SMB header to the next wct field.
1984 * None of the AndX requests put anything valuable in vwv[0] and [1],
1985 * so we can overwrite it here to form the chain.
1988 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1989 if (req->chain_outbuf == NULL) {
1990 req->chain_outbuf = talloc_realloc(
1991 req, req->outbuf, uint8_t,
1992 smb_len(req->outbuf) + 4);
1993 if (req->chain_outbuf == NULL) {
1994 smb_panic("talloc failed");
1997 req->outbuf = NULL;
1998 goto error;
2002 * Here we assume that this is the end of the chain. For that we need
2003 * to set "next command" to 0xff and the offset to 0. If we later find
2004 * more commands in the chain, this will be overwritten again.
2007 SCVAL(req->outbuf, smb_vwv0, 0xff);
2008 SCVAL(req->outbuf, smb_vwv0+1, 0);
2009 SSVAL(req->outbuf, smb_vwv1, 0);
2011 if (req->chain_outbuf == NULL) {
2013 * In req->chain_outbuf we collect all the replies. Start the
2014 * chain by copying in the first reply.
2016 * We do the realloc because later on we depend on
2017 * talloc_get_size to determine the length of
2018 * chain_outbuf. The reply_xxx routines might have
2019 * over-allocated (reply_pipe_read_and_X used to be such an
2020 * example).
2022 req->chain_outbuf = talloc_realloc(
2023 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2024 if (req->chain_outbuf == NULL) {
2025 smb_panic("talloc failed");
2027 req->outbuf = NULL;
2028 } else {
2030 * Update smb headers where subsequent chained commands
2031 * may have updated them.
2033 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2034 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2036 if (!smb_splice_chain(&req->chain_outbuf,
2037 CVAL(req->outbuf, smb_com),
2038 CVAL(req->outbuf, smb_wct),
2039 (uint16_t *)(req->outbuf + smb_vwv),
2040 0, smb_buflen(req->outbuf),
2041 (uint8_t *)smb_buf(req->outbuf))) {
2042 goto error;
2044 TALLOC_FREE(req->outbuf);
2048 * We use the old request's vwv field to grab the next chained command
2049 * and offset into the chained fields.
2052 chain_cmd = CVAL(req->vwv+0, 0);
2053 chain_offset = SVAL(req->vwv+1, 0);
2055 if (chain_cmd == 0xff) {
2057 * End of chain, no more requests from the client. So ship the
2058 * replies.
2060 smb_setlen((char *)(req->chain_outbuf),
2061 talloc_get_size(req->chain_outbuf) - 4);
2063 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2064 true, req->seqnum+1,
2065 IS_CONN_ENCRYPTED(req->conn)
2066 ||req->encrypted,
2067 &req->pcd)) {
2068 exit_server_cleanly("chain_reply: srv_send_smb "
2069 "failed.");
2071 TALLOC_FREE(req->chain_outbuf);
2072 req->done = true;
2073 return;
2076 /* add a new perfcounter for this element of chain */
2077 SMB_PERFCOUNT_ADD(&req->pcd);
2078 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2079 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2082 * Check if the client tries to fool us. The chain offset
2083 * needs to point beyond the current request in the chain, it
2084 * needs to strictly grow. Otherwise we might be tricked into
2085 * an endless loop always processing the same request over and
2086 * over again. We used to assume that vwv and the byte buffer
2087 * array in a chain are always attached, but OS/2 the
2088 * Write&X/Read&X chain puts the Read&X vwv array right behind
2089 * the Write&X vwv chain. The Write&X bcc array is put behind
2090 * the Read&X vwv array. So now we check whether the chain
2091 * offset points strictly behind the previous vwv
2092 * array. req->buf points right after the vwv array of the
2093 * previous request. See
2094 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2095 * information.
2098 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2099 if (chain_offset <= already_used) {
2100 goto error;
2104 * Next check: Make sure the chain offset does not point beyond the
2105 * overall smb request length.
2108 length_needed = chain_offset+1; /* wct */
2109 if (length_needed > smblen) {
2110 goto error;
2114 * Now comes the pointer magic. Goal here is to set up req->vwv and
2115 * req->buf correctly again to be able to call the subsequent
2116 * switch_message(). The chain offset (the former vwv[1]) points at
2117 * the new wct field.
2120 wct = CVAL(smb_base(req->inbuf), chain_offset);
2123 * Next consistency check: Make the new vwv array fits in the overall
2124 * smb request.
2127 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2128 if (length_needed > smblen) {
2129 goto error;
2131 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2134 * Now grab the new byte buffer....
2137 buflen = SVAL(vwv+wct, 0);
2140 * .. and check that it fits.
2143 length_needed += buflen;
2144 if (length_needed > smblen) {
2145 goto error;
2147 buf = (const uint8_t *)(vwv+wct+1);
2149 req->cmd = chain_cmd;
2150 req->wct = wct;
2151 req->vwv = discard_const_p(uint16_t, vwv);
2152 req->buflen = buflen;
2153 req->buf = buf;
2155 switch_message(chain_cmd, req, smblen);
2157 if (req->outbuf == NULL) {
2159 * This happens if the chained command has suspended itself or
2160 * if it has called srv_send_smb() itself.
2162 return;
2166 * We end up here if the chained command was not itself chained or
2167 * suspended, but for example a close() command. We now need to splice
2168 * the chained commands' outbuf into the already built up chain_outbuf
2169 * and ship the result.
2171 goto done;
2173 error:
2175 * We end up here if there's any error in the chain syntax. Report a
2176 * DOS error, just like Windows does.
2178 reply_force_doserror(req, ERRSRV, ERRerror);
2179 fixup_chain_error_packet(req);
2181 done:
2183 * This scary statement intends to set the
2184 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2185 * to the value req->outbuf carries
2187 SSVAL(req->chain_outbuf, smb_flg2,
2188 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2189 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2192 * Transfer the error codes from the subrequest to the main one
2194 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2195 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2197 if (!smb_splice_chain(&req->chain_outbuf,
2198 CVAL(req->outbuf, smb_com),
2199 CVAL(req->outbuf, smb_wct),
2200 (uint16_t *)(req->outbuf + smb_vwv),
2201 0, smb_buflen(req->outbuf),
2202 (uint8_t *)smb_buf(req->outbuf))) {
2203 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2205 TALLOC_FREE(req->outbuf);
2207 smb_setlen((char *)(req->chain_outbuf),
2208 talloc_get_size(req->chain_outbuf) - 4);
2210 show_msg((char *)(req->chain_outbuf));
2212 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2213 true, req->seqnum+1,
2214 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2215 &req->pcd)) {
2216 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2218 TALLOC_FREE(req->chain_outbuf);
2219 req->done = true;
2222 /****************************************************************************
2223 Check if services need reloading.
2224 ****************************************************************************/
2226 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2229 if (last_smb_conf_reload_time == 0) {
2230 last_smb_conf_reload_time = t;
2233 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2234 reload_services(sconn, conn_snum_used, true);
2235 last_smb_conf_reload_time = t;
2239 static bool fd_is_readable(int fd)
2241 int ret, revents;
2243 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2245 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2249 static void smbd_server_connection_write_handler(
2250 struct smbd_server_connection *sconn)
2252 /* TODO: make write nonblocking */
2255 static void smbd_server_connection_read_handler(
2256 struct smbd_server_connection *sconn, int fd)
2258 uint8_t *inbuf = NULL;
2259 size_t inbuf_len = 0;
2260 size_t unread_bytes = 0;
2261 bool encrypted = false;
2262 TALLOC_CTX *mem_ctx = talloc_tos();
2263 NTSTATUS status;
2264 uint32_t seqnum;
2266 bool from_client;
2268 if (lp_async_smb_echo_handler()
2269 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2271 * This is the super-ugly hack to prefer the packets
2272 * forwarded by the echo handler over the ones by the
2273 * client directly
2275 fd = sconn->smb1.echo_handler.trusted_fd;
2278 from_client = (sconn->sock == fd);
2280 if (from_client) {
2281 smbd_lock_socket(sconn);
2283 if (!fd_is_readable(fd)) {
2284 DEBUG(10,("the echo listener was faster\n"));
2285 smbd_unlock_socket(sconn);
2286 return;
2290 /* TODO: make this completely nonblocking */
2291 status = receive_smb_talloc(mem_ctx, sconn, fd,
2292 (char **)(void *)&inbuf,
2293 0, /* timeout */
2294 &unread_bytes,
2295 &encrypted,
2296 &inbuf_len, &seqnum,
2297 false /* trusted channel */);
2299 if (from_client) {
2300 smbd_unlock_socket(sconn);
2303 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2304 goto process;
2306 if (NT_STATUS_IS_ERR(status)) {
2307 exit_server_cleanly("failed to receive smb request");
2309 if (!NT_STATUS_IS_OK(status)) {
2310 return;
2313 process:
2314 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2315 seqnum, encrypted, NULL);
2318 static void smbd_server_connection_handler(struct event_context *ev,
2319 struct fd_event *fde,
2320 uint16_t flags,
2321 void *private_data)
2323 struct smbd_server_connection *conn = talloc_get_type(private_data,
2324 struct smbd_server_connection);
2326 if (flags & EVENT_FD_WRITE) {
2327 smbd_server_connection_write_handler(conn);
2328 return;
2330 if (flags & EVENT_FD_READ) {
2331 smbd_server_connection_read_handler(conn, conn->sock);
2332 return;
2336 static void smbd_server_echo_handler(struct event_context *ev,
2337 struct fd_event *fde,
2338 uint16_t flags,
2339 void *private_data)
2341 struct smbd_server_connection *conn = talloc_get_type(private_data,
2342 struct smbd_server_connection);
2344 if (flags & EVENT_FD_WRITE) {
2345 smbd_server_connection_write_handler(conn);
2346 return;
2348 if (flags & EVENT_FD_READ) {
2349 smbd_server_connection_read_handler(
2350 conn, conn->smb1.echo_handler.trusted_fd);
2351 return;
2355 #ifdef CLUSTER_SUPPORT
2356 /****************************************************************************
2357 received when we should release a specific IP
2358 ****************************************************************************/
2359 static void release_ip(const char *ip, void *priv)
2361 const char *addr = (const char *)priv;
2362 const char *p = addr;
2364 if (strncmp("::ffff:", addr, 7) == 0) {
2365 p = addr + 7;
2368 DEBUG(10, ("Got release IP message for %s, "
2369 "our address is %s\n", ip, p));
2371 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2372 /* we can't afford to do a clean exit - that involves
2373 database writes, which would potentially mean we
2374 are still running after the failover has finished -
2375 we have to get rid of this process ID straight
2376 away */
2377 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2378 ip));
2379 /* note we must exit with non-zero status so the unclean handler gets
2380 called in the parent, so that the brl database is tickled */
2381 _exit(1);
2385 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2386 struct sockaddr_storage *client)
2388 socklen_t length;
2389 length = sizeof(*server);
2390 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2391 return -1;
2393 length = sizeof(*client);
2394 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2395 return -1;
2397 return 0;
2399 #endif
2402 * Send keepalive packets to our client
2404 static bool keepalive_fn(const struct timeval *now, void *private_data)
2406 struct smbd_server_connection *sconn = talloc_get_type_abort(
2407 private_data, struct smbd_server_connection);
2408 bool ret;
2410 if (sconn->using_smb2) {
2411 /* Don't do keepalives on an SMB2 connection. */
2412 return false;
2415 smbd_lock_socket(sconn);
2416 ret = send_keepalive(sconn->sock);
2417 smbd_unlock_socket(sconn);
2419 if (!ret) {
2420 char addr[INET6_ADDRSTRLEN];
2422 * Try and give an error message saying what
2423 * client failed.
2425 DEBUG(0, ("send_keepalive failed for client %s. "
2426 "Error %s - exiting\n",
2427 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2428 strerror(errno)));
2429 return False;
2431 return True;
2435 * Do the recurring check if we're idle
2437 static bool deadtime_fn(const struct timeval *now, void *private_data)
2439 struct smbd_server_connection *sconn =
2440 (struct smbd_server_connection *)private_data;
2442 if ((conn_num_open(sconn) == 0)
2443 || (conn_idle_all(sconn, now->tv_sec))) {
2444 DEBUG( 2, ( "Closing idle connection\n" ) );
2445 messaging_send(sconn->msg_ctx,
2446 messaging_server_id(sconn->msg_ctx),
2447 MSG_SHUTDOWN, &data_blob_null);
2448 return False;
2451 return True;
2455 * Do the recurring log file and smb.conf reload checks.
2458 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2460 struct smbd_server_connection *sconn = talloc_get_type_abort(
2461 private_data, struct smbd_server_connection);
2463 DEBUG(5, ("housekeeping\n"));
2465 change_to_root_user();
2467 /* update printer queue caches if necessary */
2468 update_monitored_printq_cache(sconn->msg_ctx);
2470 /* check if we need to reload services */
2471 check_reload(sconn, time_mono(NULL));
2473 /* Change machine password if neccessary. */
2474 attempt_machine_password_change();
2477 * Force a log file check.
2479 force_check_log_size();
2480 check_log_size();
2481 return true;
2485 * Read an smb packet in the echo handler child, giving the parent
2486 * smbd one second to react once the socket becomes readable.
2489 struct smbd_echo_read_state {
2490 struct tevent_context *ev;
2491 struct smbd_server_connection *sconn;
2493 char *buf;
2494 size_t buflen;
2495 uint32_t seqnum;
2498 static void smbd_echo_read_readable(struct tevent_req *subreq);
2499 static void smbd_echo_read_waited(struct tevent_req *subreq);
2501 static struct tevent_req *smbd_echo_read_send(
2502 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2503 struct smbd_server_connection *sconn)
2505 struct tevent_req *req, *subreq;
2506 struct smbd_echo_read_state *state;
2508 req = tevent_req_create(mem_ctx, &state,
2509 struct smbd_echo_read_state);
2510 if (req == NULL) {
2511 return NULL;
2513 state->ev = ev;
2514 state->sconn = sconn;
2516 subreq = wait_for_read_send(state, ev, sconn->sock);
2517 if (tevent_req_nomem(subreq, req)) {
2518 return tevent_req_post(req, ev);
2520 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2521 return req;
2524 static void smbd_echo_read_readable(struct tevent_req *subreq)
2526 struct tevent_req *req = tevent_req_callback_data(
2527 subreq, struct tevent_req);
2528 struct smbd_echo_read_state *state = tevent_req_data(
2529 req, struct smbd_echo_read_state);
2530 bool ok;
2531 int err;
2533 ok = wait_for_read_recv(subreq, &err);
2534 TALLOC_FREE(subreq);
2535 if (!ok) {
2536 tevent_req_nterror(req, map_nt_error_from_unix(err));
2537 return;
2541 * Give the parent smbd one second to step in
2544 subreq = tevent_wakeup_send(
2545 state, state->ev, timeval_current_ofs(1, 0));
2546 if (tevent_req_nomem(subreq, req)) {
2547 return;
2549 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2552 static void smbd_echo_read_waited(struct tevent_req *subreq)
2554 struct tevent_req *req = tevent_req_callback_data(
2555 subreq, struct tevent_req);
2556 struct smbd_echo_read_state *state = tevent_req_data(
2557 req, struct smbd_echo_read_state);
2558 struct smbd_server_connection *sconn = state->sconn;
2559 bool ok;
2560 NTSTATUS status;
2561 size_t unread = 0;
2562 bool encrypted;
2564 ok = tevent_wakeup_recv(subreq);
2565 TALLOC_FREE(subreq);
2566 if (!ok) {
2567 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2568 return;
2571 ok = smbd_lock_socket_internal(sconn);
2572 if (!ok) {
2573 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2574 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2575 return;
2578 if (!fd_is_readable(sconn->sock)) {
2579 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2580 (int)sys_getpid()));
2582 ok = smbd_unlock_socket_internal(sconn);
2583 if (!ok) {
2584 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2585 DEBUG(1, ("%s: failed to unlock socket\n",
2586 __location__));
2587 return;
2590 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2591 if (tevent_req_nomem(subreq, req)) {
2592 return;
2594 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2595 return;
2598 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2599 0 /* timeout */,
2600 &unread,
2601 &encrypted,
2602 &state->buflen,
2603 &state->seqnum,
2604 false /* trusted_channel*/);
2606 if (tevent_req_nterror(req, status)) {
2607 tevent_req_nterror(req, status);
2608 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2609 (int)sys_getpid(), nt_errstr(status)));
2610 return;
2613 ok = smbd_unlock_socket_internal(sconn);
2614 if (!ok) {
2615 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2616 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2617 return;
2619 tevent_req_done(req);
2622 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2623 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2625 struct smbd_echo_read_state *state = tevent_req_data(
2626 req, struct smbd_echo_read_state);
2627 NTSTATUS status;
2629 if (tevent_req_is_nterror(req, &status)) {
2630 return status;
2632 *pbuf = talloc_move(mem_ctx, &state->buf);
2633 *pbuflen = state->buflen;
2634 *pseqnum = state->seqnum;
2635 return NT_STATUS_OK;
2638 struct smbd_echo_state {
2639 struct tevent_context *ev;
2640 struct iovec *pending;
2641 struct smbd_server_connection *sconn;
2642 int parent_pipe;
2644 struct tevent_fd *parent_fde;
2646 struct tevent_req *write_req;
2649 static void smbd_echo_writer_done(struct tevent_req *req);
2651 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2653 int num_pending;
2655 if (state->write_req != NULL) {
2656 return;
2659 num_pending = talloc_array_length(state->pending);
2660 if (num_pending == 0) {
2661 return;
2664 state->write_req = writev_send(state, state->ev, NULL,
2665 state->parent_pipe, false,
2666 state->pending, num_pending);
2667 if (state->write_req == NULL) {
2668 DEBUG(1, ("writev_send failed\n"));
2669 exit(1);
2672 talloc_steal(state->write_req, state->pending);
2673 state->pending = NULL;
2675 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2676 state);
2679 static void smbd_echo_writer_done(struct tevent_req *req)
2681 struct smbd_echo_state *state = tevent_req_callback_data(
2682 req, struct smbd_echo_state);
2683 ssize_t written;
2684 int err;
2686 written = writev_recv(req, &err);
2687 TALLOC_FREE(req);
2688 state->write_req = NULL;
2689 if (written == -1) {
2690 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2691 exit(1);
2693 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2694 smbd_echo_activate_writer(state);
2697 static bool smbd_echo_reply(struct smbd_echo_state *state,
2698 uint8_t *inbuf, size_t inbuf_len,
2699 uint32_t seqnum)
2701 struct smb_request req;
2702 uint16_t num_replies;
2703 size_t out_len;
2704 char *outbuf;
2705 bool ok;
2707 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2708 DEBUG(10, ("Got netbios keepalive\n"));
2710 * Just swallow it
2712 return true;
2715 if (inbuf_len < smb_size) {
2716 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2717 return false;
2719 if (!valid_smb_header(state->sconn, inbuf)) {
2720 DEBUG(10, ("Got invalid SMB header\n"));
2721 return false;
2724 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2725 seqnum)) {
2726 return false;
2728 req.inbuf = inbuf;
2730 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2731 smb_messages[req.cmd].name
2732 ? smb_messages[req.cmd].name : "unknown"));
2734 if (req.cmd != SMBecho) {
2735 return false;
2737 if (req.wct < 1) {
2738 return false;
2741 num_replies = SVAL(req.vwv+0, 0);
2742 if (num_replies != 1) {
2743 /* Not a Windows "Hey, you're still there?" request */
2744 return false;
2747 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2748 1, req.buflen)) {
2749 DEBUG(10, ("create_outbuf failed\n"));
2750 return false;
2752 req.outbuf = (uint8_t *)outbuf;
2754 SSVAL(req.outbuf, smb_vwv0, num_replies);
2756 if (req.buflen > 0) {
2757 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2760 out_len = smb_len(req.outbuf) + 4;
2762 ok = srv_send_smb(req.sconn,
2763 (char *)outbuf,
2764 true, seqnum+1,
2765 false, &req.pcd);
2766 TALLOC_FREE(outbuf);
2767 if (!ok) {
2768 exit(1);
2771 return true;
2774 static void smbd_echo_exit(struct tevent_context *ev,
2775 struct tevent_fd *fde, uint16_t flags,
2776 void *private_data)
2778 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2779 exit(0);
2782 static void smbd_echo_got_packet(struct tevent_req *req);
2784 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2785 int parent_pipe)
2787 struct smbd_echo_state *state;
2788 struct tevent_req *read_req;
2790 state = talloc_zero(sconn, struct smbd_echo_state);
2791 if (state == NULL) {
2792 DEBUG(1, ("talloc failed\n"));
2793 return;
2795 state->sconn = sconn;
2796 state->parent_pipe = parent_pipe;
2797 state->ev = s3_tevent_context_init(state);
2798 if (state->ev == NULL) {
2799 DEBUG(1, ("tevent_context_init failed\n"));
2800 TALLOC_FREE(state);
2801 return;
2803 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2804 TEVENT_FD_READ, smbd_echo_exit,
2805 state);
2806 if (state->parent_fde == NULL) {
2807 DEBUG(1, ("tevent_add_fd failed\n"));
2808 TALLOC_FREE(state);
2809 return;
2812 read_req = smbd_echo_read_send(state, state->ev, sconn);
2813 if (read_req == NULL) {
2814 DEBUG(1, ("smbd_echo_read_send failed\n"));
2815 TALLOC_FREE(state);
2816 return;
2818 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2820 while (true) {
2821 if (tevent_loop_once(state->ev) == -1) {
2822 DEBUG(1, ("tevent_loop_once failed: %s\n",
2823 strerror(errno)));
2824 break;
2827 TALLOC_FREE(state);
2830 static void smbd_echo_got_packet(struct tevent_req *req)
2832 struct smbd_echo_state *state = tevent_req_callback_data(
2833 req, struct smbd_echo_state);
2834 NTSTATUS status;
2835 char *buf = NULL;
2836 size_t buflen = 0;
2837 uint32_t seqnum = 0;
2838 bool reply;
2840 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2841 TALLOC_FREE(req);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2844 nt_errstr(status)));
2845 exit(1);
2848 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2849 if (!reply) {
2850 size_t num_pending;
2851 struct iovec *tmp;
2852 struct iovec *iov;
2854 num_pending = talloc_array_length(state->pending);
2855 tmp = talloc_realloc(state, state->pending, struct iovec,
2856 num_pending+1);
2857 if (tmp == NULL) {
2858 DEBUG(1, ("talloc_realloc failed\n"));
2859 exit(1);
2861 state->pending = tmp;
2863 if (buflen >= smb_size) {
2865 * place the seqnum in the packet so that the main process
2866 * can reply with signing
2868 SIVAL(buf, smb_ss_field, seqnum);
2869 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2872 iov = &state->pending[num_pending];
2873 iov->iov_base = buf;
2874 iov->iov_len = buflen;
2876 DEBUG(10,("echo_handler[%d]: forward to main\n",
2877 (int)sys_getpid()));
2878 smbd_echo_activate_writer(state);
2881 req = smbd_echo_read_send(state, state->ev, state->sconn);
2882 if (req == NULL) {
2883 DEBUG(1, ("smbd_echo_read_send failed\n"));
2884 exit(1);
2886 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2891 * Handle SMBecho requests in a forked child process
2893 bool fork_echo_handler(struct smbd_server_connection *sconn)
2895 int listener_pipe[2];
2896 int res;
2897 pid_t child;
2899 res = pipe(listener_pipe);
2900 if (res == -1) {
2901 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2902 return false;
2904 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2905 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2906 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2907 goto fail;
2910 child = sys_fork();
2911 if (child == 0) {
2912 NTSTATUS status;
2914 close(listener_pipe[0]);
2915 set_blocking(listener_pipe[1], false);
2917 status = reinit_after_fork(sconn->msg_ctx,
2918 sconn->ev_ctx,
2919 false);
2920 if (!NT_STATUS_IS_OK(status)) {
2921 DEBUG(1, ("reinit_after_fork failed: %s\n",
2922 nt_errstr(status)));
2923 exit(1);
2925 smbd_echo_loop(sconn, listener_pipe[1]);
2926 exit(0);
2928 close(listener_pipe[1]);
2929 listener_pipe[1] = -1;
2930 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2932 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2935 * Without smb signing this is the same as the normal smbd
2936 * listener. This needs to change once signing comes in.
2938 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2939 sconn,
2940 sconn->smb1.echo_handler.trusted_fd,
2941 TEVENT_FD_READ,
2942 smbd_server_echo_handler,
2943 sconn);
2944 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2945 DEBUG(1, ("event_add_fd failed\n"));
2946 goto fail;
2949 return true;
2951 fail:
2952 if (listener_pipe[0] != -1) {
2953 close(listener_pipe[0]);
2955 if (listener_pipe[1] != -1) {
2956 close(listener_pipe[1]);
2958 sconn->smb1.echo_handler.trusted_fd = -1;
2959 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2960 close(sconn->smb1.echo_handler.socket_lock_fd);
2962 sconn->smb1.echo_handler.trusted_fd = -1;
2963 sconn->smb1.echo_handler.socket_lock_fd = -1;
2964 return false;
2967 #if CLUSTER_SUPPORT
2969 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2970 struct sockaddr_storage *srv,
2971 struct sockaddr_storage *clnt)
2973 struct ctdbd_connection *cconn;
2974 char tmp_addr[INET6_ADDRSTRLEN];
2975 char *addr;
2977 cconn = messaging_ctdbd_connection();
2978 if (cconn == NULL) {
2979 return NT_STATUS_NO_MEMORY;
2982 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2983 addr = talloc_strdup(cconn, tmp_addr);
2984 if (addr == NULL) {
2985 return NT_STATUS_NO_MEMORY;
2987 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2990 #endif
2992 static bool uid_in_use(const struct user_struct *user, uid_t uid)
2994 while (user) {
2995 if (user->session_info &&
2996 (user->session_info->unix_token->uid == uid)) {
2997 return true;
2999 user = user->next;
3001 return false;
3004 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3006 while (user) {
3007 if (user->session_info != NULL) {
3008 int i;
3009 struct security_unix_token *utok;
3011 utok = user->session_info->unix_token;
3012 if (utok->gid == gid) {
3013 return true;
3015 for(i=0; i<utok->ngroups; i++) {
3016 if (utok->groups[i] == gid) {
3017 return true;
3021 user = user->next;
3023 return false;
3026 static bool sid_in_use(const struct user_struct *user,
3027 const struct dom_sid *psid)
3029 while (user) {
3030 struct security_token *tok;
3032 if (user->session_info == NULL) {
3033 continue;
3035 tok = user->session_info->security_token;
3036 if (tok == NULL) {
3038 * Not sure session_info->security_token can
3039 * ever be NULL. This check might be not
3040 * necessary.
3042 continue;
3044 if (security_token_has_sid(tok, psid)) {
3045 return true;
3047 user = user->next;
3049 return false;
3052 static bool id_in_use(const struct user_struct *user,
3053 const struct id_cache_ref *id)
3055 switch(id->type) {
3056 case UID:
3057 return uid_in_use(user, id->id.uid);
3058 case GID:
3059 return gid_in_use(user, id->id.gid);
3060 case SID:
3061 return sid_in_use(user, &id->id.sid);
3062 default:
3063 break;
3065 return false;
3068 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3069 void *private_data,
3070 uint32_t msg_type,
3071 struct server_id server_id,
3072 DATA_BLOB* data)
3074 const char *msg = (data && data->data)
3075 ? (const char *)data->data : "<NULL>";
3076 struct user_struct *validated_users;
3077 struct id_cache_ref id;
3078 struct smbd_server_connection *sconn =
3079 talloc_get_type_abort(private_data,
3080 struct smbd_server_connection);
3082 validated_users = sconn->smb1.sessions.validated_users;
3084 if (!id_cache_ref_parse(msg, &id)) {
3085 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3086 return;
3089 if (id_in_use(validated_users, &id)) {
3090 exit_server_cleanly(msg);
3092 id_cache_delete_from_cache(&id);
3095 /****************************************************************************
3096 Process commands from the client
3097 ****************************************************************************/
3099 void smbd_process(struct tevent_context *ev_ctx,
3100 struct smbd_server_connection *sconn)
3102 TALLOC_CTX *frame = talloc_stackframe();
3103 struct sockaddr_storage ss;
3104 struct sockaddr *sa = NULL;
3105 socklen_t sa_socklen;
3106 struct tsocket_address *local_address = NULL;
3107 struct tsocket_address *remote_address = NULL;
3108 const char *locaddr = NULL;
3109 const char *remaddr = NULL;
3110 char *rhost;
3111 int ret;
3113 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
3115 * We're not making the decision here,
3116 * we're just allowing the client
3117 * to decide between SMB1 and SMB2
3118 * with the first negprot
3119 * packet.
3121 sconn->using_smb2 = true;
3124 /* Ensure child is set to blocking mode */
3125 set_blocking(sconn->sock,True);
3127 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3128 set_socket_options(sconn->sock, lp_socket_options());
3130 sa = (struct sockaddr *)(void *)&ss;
3131 sa_socklen = sizeof(ss);
3132 ret = getpeername(sconn->sock, sa, &sa_socklen);
3133 if (ret != 0) {
3134 int level = (errno == ENOTCONN)?2:0;
3135 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3136 exit_server_cleanly("getpeername() failed.\n");
3138 ret = tsocket_address_bsd_from_sockaddr(sconn,
3139 sa, sa_socklen,
3140 &remote_address);
3141 if (ret != 0) {
3142 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3143 __location__, strerror(errno)));
3144 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3147 sa = (struct sockaddr *)(void *)&ss;
3148 sa_socklen = sizeof(ss);
3149 ret = getsockname(sconn->sock, sa, &sa_socklen);
3150 if (ret != 0) {
3151 int level = (errno == ENOTCONN)?2:0;
3152 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3153 exit_server_cleanly("getsockname() failed.\n");
3155 ret = tsocket_address_bsd_from_sockaddr(sconn,
3156 sa, sa_socklen,
3157 &local_address);
3158 if (ret != 0) {
3159 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3160 __location__, strerror(errno)));
3161 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3164 sconn->local_address = local_address;
3165 sconn->remote_address = remote_address;
3167 if (tsocket_address_is_inet(local_address, "ip")) {
3168 locaddr = tsocket_address_inet_addr_string(
3169 sconn->local_address,
3170 talloc_tos());
3171 if (locaddr == NULL) {
3172 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3173 __location__, strerror(errno)));
3174 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3176 } else {
3177 locaddr = "0.0.0.0";
3180 if (tsocket_address_is_inet(remote_address, "ip")) {
3181 remaddr = tsocket_address_inet_addr_string(
3182 sconn->remote_address,
3183 talloc_tos());
3184 if (remaddr == NULL) {
3185 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3186 __location__, strerror(errno)));
3187 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3189 } else {
3190 remaddr = "0.0.0.0";
3193 /* this is needed so that we get decent entries
3194 in smbstatus for port 445 connects */
3195 set_remote_machine_name(remaddr, false);
3196 reload_services(sconn, conn_snum_used, true);
3199 * Before the first packet, check the global hosts allow/ hosts deny
3200 * parameters before doing any parsing of packets passed to us by the
3201 * client. This prevents attacks on our parsing code from hosts not in
3202 * the hosts allow list.
3205 ret = get_remote_hostname(remote_address,
3206 &rhost,
3207 talloc_tos());
3208 if (ret < 0) {
3209 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3210 __location__, strerror(errno)));
3211 exit_server_cleanly("get_remote_hostname failed.\n");
3213 if (strequal(rhost, "UNKNOWN")) {
3214 rhost = talloc_strdup(talloc_tos(), remaddr);
3216 sconn->remote_hostname = talloc_move(sconn, &rhost);
3218 sub_set_socket_ids(remaddr,
3219 sconn->remote_hostname,
3220 locaddr);
3222 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3223 sconn->remote_hostname,
3224 remaddr)) {
3226 * send a negative session response "not listening on calling
3227 * name"
3229 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3230 DEBUG( 1, ("Connection denied from %s to %s\n",
3231 tsocket_address_string(remote_address, talloc_tos()),
3232 tsocket_address_string(local_address, talloc_tos())));
3233 (void)srv_send_smb(sconn,(char *)buf, false,
3234 0, false, NULL);
3235 exit_server_cleanly("connection denied");
3238 DEBUG(10, ("Connection allowed from %s to %s\n",
3239 tsocket_address_string(remote_address, talloc_tos()),
3240 tsocket_address_string(local_address, talloc_tos())));
3242 init_modules();
3244 smb_perfcount_init();
3246 if (!init_account_policy()) {
3247 exit_server("Could not open account policy tdb.\n");
3250 if (*lp_rootdir()) {
3251 if (chroot(lp_rootdir()) != 0) {
3252 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3253 exit_server("Failed to chroot()");
3255 if (chdir("/") == -1) {
3256 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3257 exit_server("Failed to chroot()");
3259 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3262 if (!srv_init_signing(sconn)) {
3263 exit_server("Failed to init smb_signing");
3266 /* Setup oplocks */
3267 if (!init_oplocks(sconn))
3268 exit_server("Failed to init oplocks");
3270 /* register our message handlers */
3271 messaging_register(sconn->msg_ctx, sconn,
3272 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3273 messaging_register(sconn->msg_ctx, sconn,
3274 MSG_SMB_CLOSE_FILE, msg_close_file);
3275 messaging_register(sconn->msg_ctx, sconn,
3276 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3278 id_cache_register_msgs(sconn->msg_ctx);
3279 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3280 messaging_register(sconn->msg_ctx, sconn,
3281 ID_CACHE_KILL, smbd_id_cache_kill);
3283 messaging_deregister(sconn->msg_ctx,
3284 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3285 messaging_register(sconn->msg_ctx, sconn,
3286 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3289 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3290 * MSGs to all child processes
3292 messaging_deregister(sconn->msg_ctx,
3293 MSG_DEBUG, NULL);
3294 messaging_register(sconn->msg_ctx, NULL,
3295 MSG_DEBUG, debug_message);
3297 if ((lp_keepalive() != 0)
3298 && !(event_add_idle(ev_ctx, NULL,
3299 timeval_set(lp_keepalive(), 0),
3300 "keepalive", keepalive_fn,
3301 sconn))) {
3302 DEBUG(0, ("Could not add keepalive event\n"));
3303 exit(1);
3306 if (!(event_add_idle(ev_ctx, NULL,
3307 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3308 "deadtime", deadtime_fn, sconn))) {
3309 DEBUG(0, ("Could not add deadtime event\n"));
3310 exit(1);
3313 if (!(event_add_idle(ev_ctx, NULL,
3314 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3315 "housekeeping", housekeeping_fn, sconn))) {
3316 DEBUG(0, ("Could not add housekeeping event\n"));
3317 exit(1);
3320 #ifdef CLUSTER_SUPPORT
3322 if (lp_clustering()) {
3324 * We need to tell ctdb about our client's TCP
3325 * connection, so that for failover ctdbd can send
3326 * tickle acks, triggering a reconnection by the
3327 * client.
3330 struct sockaddr_storage srv, clnt;
3332 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3333 NTSTATUS status;
3334 status = smbd_register_ips(sconn, &srv, &clnt);
3335 if (!NT_STATUS_IS_OK(status)) {
3336 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3337 nt_errstr(status)));
3339 } else
3341 DEBUG(0,("Unable to get tcp info for "
3342 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3343 strerror(errno)));
3347 #endif
3349 sconn->nbt.got_session = false;
3351 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3353 sconn->smb1.sessions.done_sesssetup = false;
3354 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3355 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3356 /* users from session setup */
3357 sconn->smb1.sessions.session_userlist = NULL;
3358 /* workgroup from session setup. */
3359 sconn->smb1.sessions.session_workgroup = NULL;
3360 /* this holds info on user ids that are already validated for this VC */
3361 sconn->smb1.sessions.validated_users = NULL;
3362 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3363 sconn->smb1.sessions.num_validated_vuids = 0;
3365 conn_init(sconn);
3366 if (!init_dptrs(sconn)) {
3367 exit_server("init_dptrs() failed");
3370 sconn->smb1.fde = event_add_fd(ev_ctx,
3371 sconn,
3372 sconn->sock,
3373 EVENT_FD_READ,
3374 smbd_server_connection_handler,
3375 sconn);
3376 if (!sconn->smb1.fde) {
3377 exit_server("failed to create smbd_server_connection fde");
3380 TALLOC_FREE(frame);
3382 while (True) {
3383 NTSTATUS status;
3385 frame = talloc_stackframe_pool(8192);
3387 errno = 0;
3389 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3390 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3391 !NT_STATUS_IS_OK(status)) {
3392 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3393 " exiting\n", nt_errstr(status)));
3394 break;
3397 TALLOC_FREE(frame);
3400 exit_server_cleanly(NULL);
3403 bool req_is_in_chain(struct smb_request *req)
3405 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3407 * We're right now handling a subsequent request, so we must
3408 * be in a chain
3410 return true;
3413 if (!is_andx_req(req->cmd)) {
3414 return false;
3417 if (req->wct < 2) {
3419 * Okay, an illegal request, but definitely not chained :-)
3421 return false;
3424 return (CVAL(req->vwv+0, 0) != 0xFF);