s3: Remove "size" param from switch_message
[Samba/id10ts.git] / source3 / smbd / process.c
blob15e1efe4a0a3db788719a57862f708b07f9ab421
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 = (const 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 req->priv_paths = NULL;
544 smb_init_perfcount_data(&req->pcd);
546 /* Ensure we have at least wct words and 2 bytes of bcc. */
547 if (smb_size + req->wct*2 > req_size) {
548 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
549 (unsigned int)req->wct,
550 (unsigned int)req_size));
551 return false;
553 /* Ensure bcc is correct. */
554 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
555 DEBUG(0,("init_smb_request: invalid bcc number %u "
556 "(wct = %u, size %u)\n",
557 (unsigned int)req->buflen,
558 (unsigned int)req->wct,
559 (unsigned int)req_size));
560 return false;
563 req->outbuf = NULL;
564 return true;
567 static void process_smb(struct smbd_server_connection *conn,
568 uint8_t *inbuf, size_t nread, size_t unread_bytes,
569 uint32_t seqnum, bool encrypted,
570 struct smb_perfcount_data *deferred_pcd);
572 static void smbd_deferred_open_timer(struct event_context *ev,
573 struct timed_event *te,
574 struct timeval _tval,
575 void *private_data)
577 struct pending_message_list *msg = talloc_get_type(private_data,
578 struct pending_message_list);
579 struct smbd_server_connection *sconn = msg->sconn;
580 TALLOC_CTX *mem_ctx = talloc_tos();
581 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
582 uint8_t *inbuf;
584 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
585 msg->buf.length);
586 if (inbuf == NULL) {
587 exit_server("smbd_deferred_open_timer: talloc failed\n");
588 return;
591 /* We leave this message on the queue so the open code can
592 know this is a retry. */
593 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
594 (unsigned long long)mid ));
596 /* Mark the message as processed so this is not
597 * re-processed in error. */
598 msg->processed = true;
600 process_smb(sconn, inbuf,
601 msg->buf.length, 0,
602 msg->seqnum, msg->encrypted, &msg->pcd);
604 /* If it's still there and was processed, remove it. */
605 msg = get_deferred_open_message_smb(sconn, mid);
606 if (msg && msg->processed) {
607 remove_deferred_open_message_smb(sconn, mid);
611 /****************************************************************************
612 Function to push a message onto the tail of a linked list of smb messages ready
613 for processing.
614 ****************************************************************************/
616 static bool push_queued_message(struct smb_request *req,
617 struct timeval request_time,
618 struct timeval end_time,
619 char *private_data, size_t private_len)
621 int msg_len = smb_len(req->inbuf) + 4;
622 struct pending_message_list *msg;
624 msg = talloc_zero(NULL, struct pending_message_list);
626 if(msg == NULL) {
627 DEBUG(0,("push_message: malloc fail (1)\n"));
628 return False;
630 msg->sconn = req->sconn;
632 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
633 if(msg->buf.data == NULL) {
634 DEBUG(0,("push_message: malloc fail (2)\n"));
635 TALLOC_FREE(msg);
636 return False;
639 msg->request_time = request_time;
640 msg->seqnum = req->seqnum;
641 msg->encrypted = req->encrypted;
642 msg->processed = false;
643 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
645 if (private_data) {
646 msg->private_data = data_blob_talloc(msg, private_data,
647 private_len);
648 if (msg->private_data.data == NULL) {
649 DEBUG(0,("push_message: malloc fail (3)\n"));
650 TALLOC_FREE(msg);
651 return False;
655 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
656 msg,
657 end_time,
658 smbd_deferred_open_timer,
659 msg);
660 if (!msg->te) {
661 DEBUG(0,("push_message: event_add_timed failed\n"));
662 TALLOC_FREE(msg);
663 return false;
666 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
667 struct pending_message_list *);
669 DEBUG(10,("push_message: pushed message length %u on "
670 "deferred_open_queue\n", (unsigned int)msg_len));
672 return True;
675 /****************************************************************************
676 Function to delete a sharing violation open message by mid.
677 ****************************************************************************/
679 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
680 uint64_t mid)
682 struct pending_message_list *pml;
684 if (sconn->using_smb2) {
685 remove_deferred_open_message_smb2(sconn, mid);
686 return;
689 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
690 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
691 DEBUG(10,("remove_deferred_open_message_smb: "
692 "deleting mid %llu len %u\n",
693 (unsigned long long)mid,
694 (unsigned int)pml->buf.length ));
695 DLIST_REMOVE(sconn->deferred_open_queue, pml);
696 TALLOC_FREE(pml);
697 return;
702 /****************************************************************************
703 Move a sharing violation open retry message to the front of the list and
704 schedule it for immediate processing.
705 ****************************************************************************/
707 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
708 uint64_t mid)
710 struct pending_message_list *pml;
711 int i = 0;
713 if (sconn->using_smb2) {
714 schedule_deferred_open_message_smb2(sconn, mid);
715 return;
718 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
719 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
721 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
722 "msg_mid = %llu\n",
723 i++,
724 (unsigned long long)msg_mid ));
726 if (mid == msg_mid) {
727 struct timed_event *te;
729 if (pml->processed) {
730 /* A processed message should not be
731 * rescheduled. */
732 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
733 "message mid %llu was already processed\n",
734 (unsigned long long)msg_mid ));
735 continue;
738 DEBUG(10,("schedule_deferred_open_message_smb: "
739 "scheduling mid %llu\n",
740 (unsigned long long)mid ));
742 te = tevent_add_timer(pml->sconn->ev_ctx,
743 pml,
744 timeval_zero(),
745 smbd_deferred_open_timer,
746 pml);
747 if (!te) {
748 DEBUG(10,("schedule_deferred_open_message_smb: "
749 "event_add_timed() failed, "
750 "skipping mid %llu\n",
751 (unsigned long long)msg_mid ));
754 TALLOC_FREE(pml->te);
755 pml->te = te;
756 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
757 return;
761 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
762 "find message mid %llu\n",
763 (unsigned long long)mid ));
766 /****************************************************************************
767 Return true if this mid is on the deferred queue and was not yet processed.
768 ****************************************************************************/
770 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
772 struct pending_message_list *pml;
774 if (sconn->using_smb2) {
775 return open_was_deferred_smb2(sconn, mid);
778 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
779 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
780 return True;
783 return False;
786 /****************************************************************************
787 Return the message queued by this mid.
788 ****************************************************************************/
790 static struct pending_message_list *get_deferred_open_message_smb(
791 struct smbd_server_connection *sconn, uint64_t mid)
793 struct pending_message_list *pml;
795 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
796 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
797 return pml;
800 return NULL;
803 /****************************************************************************
804 Get the state data queued by this mid.
805 ****************************************************************************/
807 bool get_deferred_open_message_state(struct smb_request *smbreq,
808 struct timeval *p_request_time,
809 void **pp_state)
811 struct pending_message_list *pml;
813 if (smbreq->sconn->using_smb2) {
814 return get_deferred_open_message_state_smb2(smbreq->smb2req,
815 p_request_time,
816 pp_state);
819 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
820 if (!pml) {
821 return false;
823 if (p_request_time) {
824 *p_request_time = pml->request_time;
826 if (pp_state) {
827 *pp_state = (void *)pml->private_data.data;
829 return true;
832 /****************************************************************************
833 Function to push a deferred open smb message onto a linked list of local smb
834 messages ready for processing.
835 ****************************************************************************/
837 bool push_deferred_open_message_smb(struct smb_request *req,
838 struct timeval request_time,
839 struct timeval timeout,
840 struct file_id id,
841 char *private_data, size_t priv_len)
843 struct timeval end_time;
845 if (req->smb2req) {
846 return push_deferred_open_message_smb2(req->smb2req,
847 request_time,
848 timeout,
850 private_data,
851 priv_len);
854 if (req->unread_bytes) {
855 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
856 "unread_bytes = %u\n",
857 (unsigned int)req->unread_bytes ));
858 smb_panic("push_deferred_open_message_smb: "
859 "logic error unread_bytes != 0" );
862 end_time = timeval_sum(&request_time, &timeout);
864 DEBUG(10,("push_deferred_open_message_smb: pushing message "
865 "len %u mid %llu timeout time [%u.%06u]\n",
866 (unsigned int) smb_len(req->inbuf)+4,
867 (unsigned long long)req->mid,
868 (unsigned int)end_time.tv_sec,
869 (unsigned int)end_time.tv_usec));
871 return push_queued_message(req, request_time, end_time,
872 private_data, priv_len);
875 static void smbd_sig_term_handler(struct tevent_context *ev,
876 struct tevent_signal *se,
877 int signum,
878 int count,
879 void *siginfo,
880 void *private_data)
882 exit_server_cleanly("termination signal");
885 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
887 struct tevent_signal *se;
889 se = tevent_add_signal(sconn->ev_ctx,
890 sconn,
891 SIGTERM, 0,
892 smbd_sig_term_handler,
893 sconn);
894 if (!se) {
895 exit_server("failed to setup SIGTERM handler");
899 static void smbd_sig_hup_handler(struct tevent_context *ev,
900 struct tevent_signal *se,
901 int signum,
902 int count,
903 void *siginfo,
904 void *private_data)
906 struct smbd_server_connection *sconn =
907 talloc_get_type_abort(private_data,
908 struct smbd_server_connection);
910 change_to_root_user();
911 DEBUG(1,("Reloading services after SIGHUP\n"));
912 reload_services(sconn, conn_snum_used, false);
915 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
917 struct tevent_signal *se;
919 se = tevent_add_signal(sconn->ev_ctx,
920 sconn,
921 SIGHUP, 0,
922 smbd_sig_hup_handler,
923 sconn);
924 if (!se) {
925 exit_server("failed to setup SIGHUP handler");
929 static void smbd_conf_updated(struct messaging_context *msg,
930 void *private_data,
931 uint32_t msg_type,
932 struct server_id server_id,
933 DATA_BLOB *data)
935 struct smbd_server_connection *sconn =
936 talloc_get_type_abort(private_data,
937 struct smbd_server_connection);
939 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
940 "updated. Reloading.\n"));
941 change_to_root_user();
942 reload_services(sconn, conn_snum_used, false);
946 * Only allow 5 outstanding trans requests. We're allocating memory, so
947 * prevent a DoS.
950 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
952 int count = 0;
953 for (; list != NULL; list = list->next) {
955 if (list->mid == mid) {
956 return NT_STATUS_INVALID_PARAMETER;
959 count += 1;
961 if (count > 5) {
962 return NT_STATUS_INSUFFICIENT_RESOURCES;
965 return NT_STATUS_OK;
969 These flags determine some of the permissions required to do an operation
971 Note that I don't set NEED_WRITE on some write operations because they
972 are used by some brain-dead clients when printing, and I don't want to
973 force write permissions on print services.
975 #define AS_USER (1<<0)
976 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
977 #define TIME_INIT (1<<2)
978 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
979 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
980 #define DO_CHDIR (1<<6)
983 define a list of possible SMB messages and their corresponding
984 functions. Any message that has a NULL function is unimplemented -
985 please feel free to contribute implementations!
987 static const struct smb_message_struct {
988 const char *name;
989 void (*fn)(struct smb_request *req);
990 int flags;
991 } smb_messages[256] = {
993 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
994 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
995 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
996 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
997 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
998 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
999 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1000 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1001 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1002 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1003 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1004 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1005 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1006 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1007 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1008 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1009 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1010 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1011 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1012 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1013 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1014 /* 0x15 */ { NULL, NULL, 0 },
1015 /* 0x16 */ { NULL, NULL, 0 },
1016 /* 0x17 */ { NULL, NULL, 0 },
1017 /* 0x18 */ { NULL, NULL, 0 },
1018 /* 0x19 */ { NULL, NULL, 0 },
1019 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1020 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1021 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1022 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1023 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1024 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1025 /* 0x20 */ { "SMBwritec", NULL,0},
1026 /* 0x21 */ { NULL, NULL, 0 },
1027 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1028 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1029 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1030 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1031 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1032 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1033 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1034 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1035 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1036 /* 0x2b */ { "SMBecho",reply_echo,0},
1037 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1038 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1039 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1040 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1041 /* 0x30 */ { NULL, NULL, 0 },
1042 /* 0x31 */ { NULL, NULL, 0 },
1043 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1044 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1045 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1046 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1047 /* 0x36 */ { NULL, NULL, 0 },
1048 /* 0x37 */ { NULL, NULL, 0 },
1049 /* 0x38 */ { NULL, NULL, 0 },
1050 /* 0x39 */ { NULL, NULL, 0 },
1051 /* 0x3a */ { NULL, NULL, 0 },
1052 /* 0x3b */ { NULL, NULL, 0 },
1053 /* 0x3c */ { NULL, NULL, 0 },
1054 /* 0x3d */ { NULL, NULL, 0 },
1055 /* 0x3e */ { NULL, NULL, 0 },
1056 /* 0x3f */ { NULL, NULL, 0 },
1057 /* 0x40 */ { NULL, NULL, 0 },
1058 /* 0x41 */ { NULL, NULL, 0 },
1059 /* 0x42 */ { NULL, NULL, 0 },
1060 /* 0x43 */ { NULL, NULL, 0 },
1061 /* 0x44 */ { NULL, NULL, 0 },
1062 /* 0x45 */ { NULL, NULL, 0 },
1063 /* 0x46 */ { NULL, NULL, 0 },
1064 /* 0x47 */ { NULL, NULL, 0 },
1065 /* 0x48 */ { NULL, NULL, 0 },
1066 /* 0x49 */ { NULL, NULL, 0 },
1067 /* 0x4a */ { NULL, NULL, 0 },
1068 /* 0x4b */ { NULL, NULL, 0 },
1069 /* 0x4c */ { NULL, NULL, 0 },
1070 /* 0x4d */ { NULL, NULL, 0 },
1071 /* 0x4e */ { NULL, NULL, 0 },
1072 /* 0x4f */ { NULL, NULL, 0 },
1073 /* 0x50 */ { NULL, NULL, 0 },
1074 /* 0x51 */ { NULL, NULL, 0 },
1075 /* 0x52 */ { NULL, NULL, 0 },
1076 /* 0x53 */ { NULL, NULL, 0 },
1077 /* 0x54 */ { NULL, NULL, 0 },
1078 /* 0x55 */ { NULL, NULL, 0 },
1079 /* 0x56 */ { NULL, NULL, 0 },
1080 /* 0x57 */ { NULL, NULL, 0 },
1081 /* 0x58 */ { NULL, NULL, 0 },
1082 /* 0x59 */ { NULL, NULL, 0 },
1083 /* 0x5a */ { NULL, NULL, 0 },
1084 /* 0x5b */ { NULL, NULL, 0 },
1085 /* 0x5c */ { NULL, NULL, 0 },
1086 /* 0x5d */ { NULL, NULL, 0 },
1087 /* 0x5e */ { NULL, NULL, 0 },
1088 /* 0x5f */ { NULL, NULL, 0 },
1089 /* 0x60 */ { NULL, NULL, 0 },
1090 /* 0x61 */ { NULL, NULL, 0 },
1091 /* 0x62 */ { NULL, NULL, 0 },
1092 /* 0x63 */ { NULL, NULL, 0 },
1093 /* 0x64 */ { NULL, NULL, 0 },
1094 /* 0x65 */ { NULL, NULL, 0 },
1095 /* 0x66 */ { NULL, NULL, 0 },
1096 /* 0x67 */ { NULL, NULL, 0 },
1097 /* 0x68 */ { NULL, NULL, 0 },
1098 /* 0x69 */ { NULL, NULL, 0 },
1099 /* 0x6a */ { NULL, NULL, 0 },
1100 /* 0x6b */ { NULL, NULL, 0 },
1101 /* 0x6c */ { NULL, NULL, 0 },
1102 /* 0x6d */ { NULL, NULL, 0 },
1103 /* 0x6e */ { NULL, NULL, 0 },
1104 /* 0x6f */ { NULL, NULL, 0 },
1105 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1106 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1107 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1108 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1109 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1110 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1111 /* 0x76 */ { NULL, NULL, 0 },
1112 /* 0x77 */ { NULL, NULL, 0 },
1113 /* 0x78 */ { NULL, NULL, 0 },
1114 /* 0x79 */ { NULL, NULL, 0 },
1115 /* 0x7a */ { NULL, NULL, 0 },
1116 /* 0x7b */ { NULL, NULL, 0 },
1117 /* 0x7c */ { NULL, NULL, 0 },
1118 /* 0x7d */ { NULL, NULL, 0 },
1119 /* 0x7e */ { NULL, NULL, 0 },
1120 /* 0x7f */ { NULL, NULL, 0 },
1121 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1122 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1123 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1124 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1125 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1126 /* 0x85 */ { NULL, NULL, 0 },
1127 /* 0x86 */ { NULL, NULL, 0 },
1128 /* 0x87 */ { NULL, NULL, 0 },
1129 /* 0x88 */ { NULL, NULL, 0 },
1130 /* 0x89 */ { NULL, NULL, 0 },
1131 /* 0x8a */ { NULL, NULL, 0 },
1132 /* 0x8b */ { NULL, NULL, 0 },
1133 /* 0x8c */ { NULL, NULL, 0 },
1134 /* 0x8d */ { NULL, NULL, 0 },
1135 /* 0x8e */ { NULL, NULL, 0 },
1136 /* 0x8f */ { NULL, NULL, 0 },
1137 /* 0x90 */ { NULL, NULL, 0 },
1138 /* 0x91 */ { NULL, NULL, 0 },
1139 /* 0x92 */ { NULL, NULL, 0 },
1140 /* 0x93 */ { NULL, NULL, 0 },
1141 /* 0x94 */ { NULL, NULL, 0 },
1142 /* 0x95 */ { NULL, NULL, 0 },
1143 /* 0x96 */ { NULL, NULL, 0 },
1144 /* 0x97 */ { NULL, NULL, 0 },
1145 /* 0x98 */ { NULL, NULL, 0 },
1146 /* 0x99 */ { NULL, NULL, 0 },
1147 /* 0x9a */ { NULL, NULL, 0 },
1148 /* 0x9b */ { NULL, NULL, 0 },
1149 /* 0x9c */ { NULL, NULL, 0 },
1150 /* 0x9d */ { NULL, NULL, 0 },
1151 /* 0x9e */ { NULL, NULL, 0 },
1152 /* 0x9f */ { NULL, NULL, 0 },
1153 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1154 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1155 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1156 /* 0xa3 */ { NULL, NULL, 0 },
1157 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1158 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1159 /* 0xa6 */ { NULL, NULL, 0 },
1160 /* 0xa7 */ { NULL, NULL, 0 },
1161 /* 0xa8 */ { NULL, NULL, 0 },
1162 /* 0xa9 */ { NULL, NULL, 0 },
1163 /* 0xaa */ { NULL, NULL, 0 },
1164 /* 0xab */ { NULL, NULL, 0 },
1165 /* 0xac */ { NULL, NULL, 0 },
1166 /* 0xad */ { NULL, NULL, 0 },
1167 /* 0xae */ { NULL, NULL, 0 },
1168 /* 0xaf */ { NULL, NULL, 0 },
1169 /* 0xb0 */ { NULL, NULL, 0 },
1170 /* 0xb1 */ { NULL, NULL, 0 },
1171 /* 0xb2 */ { NULL, NULL, 0 },
1172 /* 0xb3 */ { NULL, NULL, 0 },
1173 /* 0xb4 */ { NULL, NULL, 0 },
1174 /* 0xb5 */ { NULL, NULL, 0 },
1175 /* 0xb6 */ { NULL, NULL, 0 },
1176 /* 0xb7 */ { NULL, NULL, 0 },
1177 /* 0xb8 */ { NULL, NULL, 0 },
1178 /* 0xb9 */ { NULL, NULL, 0 },
1179 /* 0xba */ { NULL, NULL, 0 },
1180 /* 0xbb */ { NULL, NULL, 0 },
1181 /* 0xbc */ { NULL, NULL, 0 },
1182 /* 0xbd */ { NULL, NULL, 0 },
1183 /* 0xbe */ { NULL, NULL, 0 },
1184 /* 0xbf */ { NULL, NULL, 0 },
1185 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1186 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1187 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1188 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1189 /* 0xc4 */ { NULL, NULL, 0 },
1190 /* 0xc5 */ { NULL, NULL, 0 },
1191 /* 0xc6 */ { NULL, NULL, 0 },
1192 /* 0xc7 */ { NULL, NULL, 0 },
1193 /* 0xc8 */ { NULL, NULL, 0 },
1194 /* 0xc9 */ { NULL, NULL, 0 },
1195 /* 0xca */ { NULL, NULL, 0 },
1196 /* 0xcb */ { NULL, NULL, 0 },
1197 /* 0xcc */ { NULL, NULL, 0 },
1198 /* 0xcd */ { NULL, NULL, 0 },
1199 /* 0xce */ { NULL, NULL, 0 },
1200 /* 0xcf */ { NULL, NULL, 0 },
1201 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1202 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1203 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1204 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1205 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1206 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1207 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1208 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1209 /* 0xd8 */ { NULL, NULL, 0 },
1210 /* 0xd9 */ { NULL, NULL, 0 },
1211 /* 0xda */ { NULL, NULL, 0 },
1212 /* 0xdb */ { NULL, NULL, 0 },
1213 /* 0xdc */ { NULL, NULL, 0 },
1214 /* 0xdd */ { NULL, NULL, 0 },
1215 /* 0xde */ { NULL, NULL, 0 },
1216 /* 0xdf */ { NULL, NULL, 0 },
1217 /* 0xe0 */ { NULL, NULL, 0 },
1218 /* 0xe1 */ { NULL, NULL, 0 },
1219 /* 0xe2 */ { NULL, NULL, 0 },
1220 /* 0xe3 */ { NULL, NULL, 0 },
1221 /* 0xe4 */ { NULL, NULL, 0 },
1222 /* 0xe5 */ { NULL, NULL, 0 },
1223 /* 0xe6 */ { NULL, NULL, 0 },
1224 /* 0xe7 */ { NULL, NULL, 0 },
1225 /* 0xe8 */ { NULL, NULL, 0 },
1226 /* 0xe9 */ { NULL, NULL, 0 },
1227 /* 0xea */ { NULL, NULL, 0 },
1228 /* 0xeb */ { NULL, NULL, 0 },
1229 /* 0xec */ { NULL, NULL, 0 },
1230 /* 0xed */ { NULL, NULL, 0 },
1231 /* 0xee */ { NULL, NULL, 0 },
1232 /* 0xef */ { NULL, NULL, 0 },
1233 /* 0xf0 */ { NULL, NULL, 0 },
1234 /* 0xf1 */ { NULL, NULL, 0 },
1235 /* 0xf2 */ { NULL, NULL, 0 },
1236 /* 0xf3 */ { NULL, NULL, 0 },
1237 /* 0xf4 */ { NULL, NULL, 0 },
1238 /* 0xf5 */ { NULL, NULL, 0 },
1239 /* 0xf6 */ { NULL, NULL, 0 },
1240 /* 0xf7 */ { NULL, NULL, 0 },
1241 /* 0xf8 */ { NULL, NULL, 0 },
1242 /* 0xf9 */ { NULL, NULL, 0 },
1243 /* 0xfa */ { NULL, NULL, 0 },
1244 /* 0xfb */ { NULL, NULL, 0 },
1245 /* 0xfc */ { NULL, NULL, 0 },
1246 /* 0xfd */ { NULL, NULL, 0 },
1247 /* 0xfe */ { NULL, NULL, 0 },
1248 /* 0xff */ { NULL, NULL, 0 }
1252 /*******************************************************************
1253 allocate and initialize a reply packet
1254 ********************************************************************/
1256 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1257 const char *inbuf, char **outbuf, uint8_t num_words,
1258 uint32_t num_bytes)
1261 * Protect against integer wrap
1263 if ((num_bytes > 0xffffff)
1264 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1265 char *msg;
1266 if (asprintf(&msg, "num_bytes too large: %u",
1267 (unsigned)num_bytes) == -1) {
1268 msg = discard_const_p(char, "num_bytes too large");
1270 smb_panic(msg);
1273 *outbuf = talloc_array(mem_ctx, char,
1274 smb_size + num_words*2 + num_bytes);
1275 if (*outbuf == NULL) {
1276 return false;
1279 construct_reply_common(req, inbuf, *outbuf);
1280 srv_set_message(*outbuf, num_words, num_bytes, false);
1282 * Zero out the word area, the caller has to take care of the bcc area
1283 * himself
1285 if (num_words != 0) {
1286 memset(*outbuf + smb_vwv0, 0, num_words*2);
1289 return true;
1292 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1294 char *outbuf;
1295 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1296 num_bytes)) {
1297 smb_panic("could not allocate output buffer\n");
1299 req->outbuf = (uint8_t *)outbuf;
1303 /*******************************************************************
1304 Dump a packet to a file.
1305 ********************************************************************/
1307 static void smb_dump(const char *name, int type, const char *data)
1309 size_t len;
1310 int fd, i;
1311 char *fname = NULL;
1312 if (DEBUGLEVEL < 50) {
1313 return;
1316 len = smb_len_tcp(data)+4;
1317 for (i=1;i<100;i++) {
1318 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1319 type ? "req" : "resp") == -1) {
1320 return;
1322 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1323 if (fd != -1 || errno != EEXIST) break;
1325 if (fd != -1) {
1326 ssize_t ret = write(fd, data, len);
1327 if (ret != len)
1328 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1329 close(fd);
1330 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1332 SAFE_FREE(fname);
1335 /****************************************************************************
1336 Prepare everything for calling the actual request function, and potentially
1337 call the request function via the "new" interface.
1339 Return False if the "legacy" function needs to be called, everything is
1340 prepared.
1342 Return True if we're done.
1344 I know this API sucks, but it is the one with the least code change I could
1345 find.
1346 ****************************************************************************/
1348 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1350 int flags;
1351 uint16 session_tag;
1352 connection_struct *conn = NULL;
1353 struct smbd_server_connection *sconn = req->sconn;
1354 char *raddr;
1356 errno = 0;
1358 if (smb_messages[type].fn == NULL) {
1359 DEBUG(0,("Unknown message type %d!\n",type));
1360 smb_dump("Unknown", 1, (const char *)req->inbuf);
1361 reply_unknown_new(req, type);
1362 return NULL;
1365 flags = smb_messages[type].flags;
1367 /* In share mode security we must ignore the vuid. */
1368 session_tag = req->vuid;
1369 conn = req->conn;
1371 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1372 (int)sys_getpid(), (unsigned long)conn));
1374 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1376 /* Ensure this value is replaced in the incoming packet. */
1377 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1380 * Ensure the correct username is in current_user_info. This is a
1381 * really ugly bugfix for problems with multiple session_setup_and_X's
1382 * being done and allowing %U and %G substitutions to work correctly.
1383 * There is a reason this code is done here, don't move it unless you
1384 * know what you're doing... :-).
1385 * JRA.
1388 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1389 user_struct *vuser = NULL;
1391 sconn->smb1.sessions.last_session_tag = session_tag;
1392 if(session_tag != UID_FIELD_INVALID) {
1393 vuser = get_valid_user_struct(sconn, session_tag);
1394 if (vuser) {
1395 set_current_user_info(
1396 vuser->session_info->unix_info->sanitized_username,
1397 vuser->session_info->unix_info->unix_name,
1398 vuser->session_info->info->domain_name);
1403 /* Does this call need to be run as the connected user? */
1404 if (flags & AS_USER) {
1406 /* Does this call need a valid tree connection? */
1407 if (!conn) {
1409 * Amazingly, the error code depends on the command
1410 * (from Samba4).
1412 if (type == SMBntcreateX) {
1413 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1414 } else {
1415 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1417 return NULL;
1420 if (!change_to_user(conn,session_tag)) {
1421 DEBUG(0, ("Error: Could not change to user. Removing "
1422 "deferred open, mid=%llu.\n",
1423 (unsigned long long)req->mid));
1424 reply_force_doserror(req, ERRSRV, ERRbaduid);
1425 return conn;
1428 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1430 /* Does it need write permission? */
1431 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1432 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1433 return conn;
1436 /* IPC services are limited */
1437 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1438 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1439 return conn;
1441 } else {
1442 /* This call needs to be run as root */
1443 change_to_root_user();
1446 /* load service specific parameters */
1447 if (conn) {
1448 if (req->encrypted) {
1449 conn->encrypted_tid = true;
1450 /* encrypted required from now on. */
1451 conn->encrypt_level = Required;
1452 } else if (ENCRYPTION_REQUIRED(conn)) {
1453 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1454 exit_server_cleanly("encryption required "
1455 "on connection");
1456 return conn;
1460 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1461 (flags & (AS_USER|DO_CHDIR)
1462 ?True:False))) {
1463 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1464 return conn;
1466 conn->num_smb_operations++;
1469 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1470 talloc_tos());
1471 if (raddr == NULL) {
1472 reply_nterror(req, NT_STATUS_NO_MEMORY);
1473 return conn;
1476 /* does this protocol need to be run as guest? */
1477 if ((flags & AS_GUEST)
1478 && (!change_to_guest() ||
1479 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1480 sconn->remote_hostname,
1481 raddr))) {
1482 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1483 return conn;
1486 smb_messages[type].fn(req);
1487 return req->conn;
1490 /****************************************************************************
1491 Construct a reply to the incoming packet.
1492 ****************************************************************************/
1494 static void construct_reply(struct smbd_server_connection *sconn,
1495 char *inbuf, int size, size_t unread_bytes,
1496 uint32_t seqnum, bool encrypted,
1497 struct smb_perfcount_data *deferred_pcd)
1499 connection_struct *conn;
1500 struct smb_request *req;
1502 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1503 smb_panic("could not allocate smb_request");
1506 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1507 encrypted, seqnum)) {
1508 exit_server_cleanly("Invalid SMB request");
1511 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1513 /* we popped this message off the queue - keep original perf data */
1514 if (deferred_pcd)
1515 req->pcd = *deferred_pcd;
1516 else {
1517 SMB_PERFCOUNT_START(&req->pcd);
1518 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1519 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1522 conn = switch_message(req->cmd, req);
1524 if (req->unread_bytes) {
1525 /* writeX failed. drain socket. */
1526 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1527 req->unread_bytes) {
1528 smb_panic("failed to drain pending bytes");
1530 req->unread_bytes = 0;
1533 if (req->done) {
1534 TALLOC_FREE(req);
1535 return;
1538 if (req->outbuf == NULL) {
1539 return;
1542 if (CVAL(req->outbuf,0) == 0) {
1543 show_msg((char *)req->outbuf);
1546 if (!srv_send_smb(req->sconn,
1547 (char *)req->outbuf,
1548 true, req->seqnum+1,
1549 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1550 &req->pcd)) {
1551 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1554 TALLOC_FREE(req);
1556 return;
1559 /****************************************************************************
1560 Process an smb from the client
1561 ****************************************************************************/
1562 static void process_smb(struct smbd_server_connection *sconn,
1563 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1564 uint32_t seqnum, bool encrypted,
1565 struct smb_perfcount_data *deferred_pcd)
1567 int msg_type = CVAL(inbuf,0);
1569 DO_PROFILE_INC(smb_count);
1571 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1572 smb_len(inbuf) ) );
1573 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1574 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1576 if (msg_type != NBSSmessage) {
1578 * NetBIOS session request, keepalive, etc.
1580 reply_special(sconn, (char *)inbuf, nread);
1581 goto done;
1584 if (sconn->using_smb2) {
1585 /* At this point we're not really using smb2,
1586 * we make the decision here.. */
1587 if (smbd_is_smb2_header(inbuf, nread)) {
1588 smbd_smb2_first_negprot(sconn, inbuf, nread);
1589 return;
1590 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1591 && CVAL(inbuf, smb_com) != 0x72) {
1592 /* This is a non-negprot SMB1 packet.
1593 Disable SMB2 from now on. */
1594 sconn->using_smb2 = false;
1598 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1599 * so subtract 4 from it. */
1600 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1601 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1602 smb_len(inbuf)));
1604 /* special magic for immediate exit */
1605 if ((nread == 9) &&
1606 (IVAL(inbuf, 4) == 0x74697865) &&
1607 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1608 uint8_t exitcode = CVAL(inbuf, 8);
1609 DEBUG(1, ("Exiting immediately with code %d\n",
1610 (int)exitcode));
1611 exit(exitcode);
1614 exit_server_cleanly("Non-SMB packet");
1617 show_msg((char *)inbuf);
1619 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1620 encrypted, deferred_pcd);
1621 sconn->trans_num++;
1623 done:
1624 sconn->num_requests++;
1626 /* The timeout_processing function isn't run nearly
1627 often enough to implement 'max log size' without
1628 overrunning the size of the file by many megabytes.
1629 This is especially true if we are running at debug
1630 level 10. Checking every 50 SMBs is a nice
1631 tradeoff of performance vs log file size overrun. */
1633 if ((sconn->num_requests % 50) == 0 &&
1634 need_to_check_log_size()) {
1635 change_to_root_user();
1636 check_log_size();
1640 /****************************************************************************
1641 Return a string containing the function name of a SMB command.
1642 ****************************************************************************/
1644 const char *smb_fn_name(int type)
1646 const char *unknown_name = "SMBunknown";
1648 if (smb_messages[type].name == NULL)
1649 return(unknown_name);
1651 return(smb_messages[type].name);
1654 /****************************************************************************
1655 Helper functions for contruct_reply.
1656 ****************************************************************************/
1658 void add_to_common_flags2(uint32 v)
1660 common_flags2 |= v;
1663 void remove_from_common_flags2(uint32 v)
1665 common_flags2 &= ~v;
1668 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1669 char *outbuf)
1671 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1672 uint16_t out_flags2 = common_flags2;
1674 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1675 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1676 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1678 srv_set_message(outbuf,0,0,false);
1680 SCVAL(outbuf, smb_com, req->cmd);
1681 SIVAL(outbuf,smb_rcls,0);
1682 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1683 SSVAL(outbuf,smb_flg2, out_flags2);
1684 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1685 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1687 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1688 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1689 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1690 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1693 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1695 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1699 * How many bytes have we already accumulated up to the current wct field
1700 * offset?
1703 size_t req_wct_ofs(struct smb_request *req)
1705 size_t buf_size;
1707 if (req->chain_outbuf == NULL) {
1708 return smb_wct - 4;
1710 buf_size = talloc_get_size(req->chain_outbuf);
1711 if ((buf_size % 4) != 0) {
1712 buf_size += (4 - (buf_size % 4));
1714 return buf_size - 4;
1718 * Hack around reply_nterror & friends not being aware of chained requests,
1719 * generating illegal (i.e. wct==0) chain replies.
1722 static void fixup_chain_error_packet(struct smb_request *req)
1724 uint8_t *outbuf = req->outbuf;
1725 req->outbuf = NULL;
1726 reply_outbuf(req, 2, 0);
1727 memcpy(req->outbuf, outbuf, smb_wct);
1728 TALLOC_FREE(outbuf);
1729 SCVAL(req->outbuf, smb_vwv0, 0xff);
1733 * @brief Find the smb_cmd offset of the last command pushed
1734 * @param[in] buf The buffer we're building up
1735 * @retval Where can we put our next andx cmd?
1737 * While chaining requests, the "next" request we're looking at needs to put
1738 * its SMB_Command before the data the previous request already built up added
1739 * to the chain. Find the offset to the place where we have to put our cmd.
1742 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1744 uint8_t cmd;
1745 size_t ofs;
1747 cmd = CVAL(buf, smb_com);
1749 if (!is_andx_req(cmd)) {
1750 return false;
1753 ofs = smb_vwv0;
1755 while (CVAL(buf, ofs) != 0xff) {
1757 if (!is_andx_req(CVAL(buf, ofs))) {
1758 return false;
1762 * ofs is from start of smb header, so add the 4 length
1763 * bytes. The next cmd is right after the wct field.
1765 ofs = SVAL(buf, ofs+2) + 4 + 1;
1767 if (ofs+4 >= talloc_get_size(buf)) {
1768 return false;
1772 *pofs = ofs;
1773 return true;
1777 * @brief Do the smb chaining at a buffer level
1778 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1779 * @param[in] andx_buf Buffer to be appended
1782 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1784 uint8_t smb_command = CVAL(andx_buf, smb_com);
1785 uint8_t wct = CVAL(andx_buf, smb_wct);
1786 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1787 uint32_t num_bytes = smb_buflen(andx_buf);
1788 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1790 uint8_t *outbuf;
1791 size_t old_size, new_size;
1792 size_t ofs;
1793 size_t chain_padding = 0;
1794 size_t andx_cmd_ofs;
1797 old_size = talloc_get_size(*poutbuf);
1799 if ((old_size % 4) != 0) {
1801 * Align the wct field of subsequent requests to a 4-byte
1802 * boundary
1804 chain_padding = 4 - (old_size % 4);
1808 * After the old request comes the new wct field (1 byte), the vwv's
1809 * and the num_bytes field.
1812 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1813 new_size += num_bytes;
1815 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1816 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1817 (unsigned)new_size));
1818 return false;
1821 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1822 if (outbuf == NULL) {
1823 DEBUG(0, ("talloc failed\n"));
1824 return false;
1826 *poutbuf = outbuf;
1828 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1829 DEBUG(1, ("invalid command chain\n"));
1830 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
1831 return false;
1834 if (chain_padding != 0) {
1835 memset(outbuf + old_size, 0, chain_padding);
1836 old_size += chain_padding;
1839 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1840 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1842 ofs = old_size;
1845 * Push the chained request:
1847 * wct field
1850 SCVAL(outbuf, ofs, wct);
1851 ofs += 1;
1854 * vwv array
1857 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1858 ofs += sizeof(uint16_t) * wct;
1861 * bcc (byte count)
1864 SSVAL(outbuf, ofs, num_bytes);
1865 ofs += sizeof(uint16_t);
1868 * The bytes field
1871 memcpy(outbuf + ofs, bytes, num_bytes);
1873 return true;
1876 /****************************************************************************
1877 Construct a chained reply and add it to the already made reply
1878 ****************************************************************************/
1880 void chain_reply(struct smb_request *req)
1882 size_t smblen = smb_len(req->inbuf);
1883 size_t already_used, length_needed;
1884 uint8_t chain_cmd;
1885 uint32_t chain_offset; /* uint32_t to avoid overflow */
1887 uint8_t wct;
1888 const uint16_t *vwv;
1889 uint16_t buflen;
1890 const uint8_t *buf;
1892 if (IVAL(req->outbuf, smb_rcls) != 0) {
1893 fixup_chain_error_packet(req);
1897 * Any of the AndX requests and replies have at least a wct of
1898 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1899 * beginning of the SMB header to the next wct field.
1901 * None of the AndX requests put anything valuable in vwv[0] and [1],
1902 * so we can overwrite it here to form the chain.
1905 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1906 if (req->chain_outbuf == NULL) {
1907 req->chain_outbuf = talloc_realloc(
1908 req, req->outbuf, uint8_t,
1909 smb_len(req->outbuf) + 4);
1910 if (req->chain_outbuf == NULL) {
1911 smb_panic("talloc failed");
1914 req->outbuf = NULL;
1915 goto error;
1919 * Here we assume that this is the end of the chain. For that we need
1920 * to set "next command" to 0xff and the offset to 0. If we later find
1921 * more commands in the chain, this will be overwritten again.
1924 SCVAL(req->outbuf, smb_vwv0, 0xff);
1925 SCVAL(req->outbuf, smb_vwv0+1, 0);
1926 SSVAL(req->outbuf, smb_vwv1, 0);
1928 if (req->chain_outbuf == NULL) {
1930 * In req->chain_outbuf we collect all the replies. Start the
1931 * chain by copying in the first reply.
1933 * We do the realloc because later on we depend on
1934 * talloc_get_size to determine the length of
1935 * chain_outbuf. The reply_xxx routines might have
1936 * over-allocated (reply_pipe_read_and_X used to be such an
1937 * example).
1939 req->chain_outbuf = talloc_realloc(
1940 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1941 if (req->chain_outbuf == NULL) {
1942 smb_panic("talloc failed");
1944 req->outbuf = NULL;
1945 } else {
1947 * Update smb headers where subsequent chained commands
1948 * may have updated them.
1950 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1951 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1953 if (!smb_splice_chain(&req->chain_outbuf, req->outbuf)) {
1954 goto error;
1956 TALLOC_FREE(req->outbuf);
1960 * We use the old request's vwv field to grab the next chained command
1961 * and offset into the chained fields.
1964 chain_cmd = CVAL(req->vwv+0, 0);
1965 chain_offset = SVAL(req->vwv+1, 0);
1967 if (chain_cmd == 0xff) {
1969 * End of chain, no more requests from the client. So ship the
1970 * replies.
1972 smb_setlen((char *)(req->chain_outbuf),
1973 talloc_get_size(req->chain_outbuf) - 4);
1975 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
1976 true, req->seqnum+1,
1977 IS_CONN_ENCRYPTED(req->conn)
1978 ||req->encrypted,
1979 &req->pcd)) {
1980 exit_server_cleanly("chain_reply: srv_send_smb "
1981 "failed.");
1983 TALLOC_FREE(req->chain_outbuf);
1984 req->done = true;
1985 return;
1988 /* add a new perfcounter for this element of chain */
1989 SMB_PERFCOUNT_ADD(&req->pcd);
1990 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1991 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1994 * Check if the client tries to fool us. The chain offset
1995 * needs to point beyond the current request in the chain, it
1996 * needs to strictly grow. Otherwise we might be tricked into
1997 * an endless loop always processing the same request over and
1998 * over again. We used to assume that vwv and the byte buffer
1999 * array in a chain are always attached, but OS/2 the
2000 * Write&X/Read&X chain puts the Read&X vwv array right behind
2001 * the Write&X vwv chain. The Write&X bcc array is put behind
2002 * the Read&X vwv array. So now we check whether the chain
2003 * offset points strictly behind the previous vwv
2004 * array. req->buf points right after the vwv array of the
2005 * previous request. See
2006 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2007 * information.
2010 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2011 if (chain_offset <= already_used) {
2012 goto error;
2016 * Next check: Make sure the chain offset does not point beyond the
2017 * overall smb request length.
2020 length_needed = chain_offset+1; /* wct */
2021 if (length_needed > smblen) {
2022 goto error;
2026 * Now comes the pointer magic. Goal here is to set up req->vwv and
2027 * req->buf correctly again to be able to call the subsequent
2028 * switch_message(). The chain offset (the former vwv[1]) points at
2029 * the new wct field.
2032 wct = CVAL(smb_base(req->inbuf), chain_offset);
2035 * Next consistency check: Make the new vwv array fits in the overall
2036 * smb request.
2039 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2040 if (length_needed > smblen) {
2041 goto error;
2043 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2046 * Now grab the new byte buffer....
2049 buflen = SVAL(vwv+wct, 0);
2052 * .. and check that it fits.
2055 length_needed += buflen;
2056 if (length_needed > smblen) {
2057 goto error;
2059 buf = (const uint8_t *)(vwv+wct+1);
2061 req->cmd = chain_cmd;
2062 req->wct = wct;
2063 req->vwv = discard_const_p(uint16_t, vwv);
2064 req->buflen = buflen;
2065 req->buf = buf;
2067 switch_message(chain_cmd, req);
2069 if (req->outbuf == NULL) {
2071 * This happens if the chained command has suspended itself or
2072 * if it has called srv_send_smb() itself.
2074 return;
2078 * We end up here if the chained command was not itself chained or
2079 * suspended, but for example a close() command. We now need to splice
2080 * the chained commands' outbuf into the already built up chain_outbuf
2081 * and ship the result.
2083 goto done;
2085 error:
2087 * We end up here if there's any error in the chain syntax. Report a
2088 * DOS error, just like Windows does.
2090 reply_force_doserror(req, ERRSRV, ERRerror);
2091 fixup_chain_error_packet(req);
2093 done:
2095 * This scary statement intends to set the
2096 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2097 * to the value req->outbuf carries
2099 SSVAL(req->chain_outbuf, smb_flg2,
2100 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2101 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2104 * Transfer the error codes from the subrequest to the main one
2106 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2107 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2109 if (!smb_splice_chain(&req->chain_outbuf, req->outbuf)) {
2110 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2112 TALLOC_FREE(req->outbuf);
2114 smb_setlen((char *)(req->chain_outbuf),
2115 talloc_get_size(req->chain_outbuf) - 4);
2117 show_msg((char *)(req->chain_outbuf));
2119 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2120 true, req->seqnum+1,
2121 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2122 &req->pcd)) {
2123 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2125 TALLOC_FREE(req->chain_outbuf);
2126 req->done = true;
2129 /****************************************************************************
2130 Check if services need reloading.
2131 ****************************************************************************/
2133 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2136 if (last_smb_conf_reload_time == 0) {
2137 last_smb_conf_reload_time = t;
2140 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2141 reload_services(sconn, conn_snum_used, true);
2142 last_smb_conf_reload_time = t;
2146 static bool fd_is_readable(int fd)
2148 int ret, revents;
2150 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2152 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2156 static void smbd_server_connection_write_handler(
2157 struct smbd_server_connection *sconn)
2159 /* TODO: make write nonblocking */
2162 static void smbd_server_connection_read_handler(
2163 struct smbd_server_connection *sconn, int fd)
2165 uint8_t *inbuf = NULL;
2166 size_t inbuf_len = 0;
2167 size_t unread_bytes = 0;
2168 bool encrypted = false;
2169 TALLOC_CTX *mem_ctx = talloc_tos();
2170 NTSTATUS status;
2171 uint32_t seqnum;
2173 bool from_client;
2175 if (lp_async_smb_echo_handler()
2176 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2178 * This is the super-ugly hack to prefer the packets
2179 * forwarded by the echo handler over the ones by the
2180 * client directly
2182 fd = sconn->smb1.echo_handler.trusted_fd;
2185 from_client = (sconn->sock == fd);
2187 if (from_client) {
2188 smbd_lock_socket(sconn);
2190 if (!fd_is_readable(fd)) {
2191 DEBUG(10,("the echo listener was faster\n"));
2192 smbd_unlock_socket(sconn);
2193 return;
2197 /* TODO: make this completely nonblocking */
2198 status = receive_smb_talloc(mem_ctx, sconn, fd,
2199 (char **)(void *)&inbuf,
2200 0, /* timeout */
2201 &unread_bytes,
2202 &encrypted,
2203 &inbuf_len, &seqnum,
2204 false /* trusted channel */);
2206 if (from_client) {
2207 smbd_unlock_socket(sconn);
2210 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2211 goto process;
2213 if (NT_STATUS_IS_ERR(status)) {
2214 exit_server_cleanly("failed to receive smb request");
2216 if (!NT_STATUS_IS_OK(status)) {
2217 return;
2220 process:
2221 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2222 seqnum, encrypted, NULL);
2225 static void smbd_server_connection_handler(struct event_context *ev,
2226 struct fd_event *fde,
2227 uint16_t flags,
2228 void *private_data)
2230 struct smbd_server_connection *conn = talloc_get_type(private_data,
2231 struct smbd_server_connection);
2233 if (flags & EVENT_FD_WRITE) {
2234 smbd_server_connection_write_handler(conn);
2235 return;
2237 if (flags & EVENT_FD_READ) {
2238 smbd_server_connection_read_handler(conn, conn->sock);
2239 return;
2243 static void smbd_server_echo_handler(struct event_context *ev,
2244 struct fd_event *fde,
2245 uint16_t flags,
2246 void *private_data)
2248 struct smbd_server_connection *conn = talloc_get_type(private_data,
2249 struct smbd_server_connection);
2251 if (flags & EVENT_FD_WRITE) {
2252 smbd_server_connection_write_handler(conn);
2253 return;
2255 if (flags & EVENT_FD_READ) {
2256 smbd_server_connection_read_handler(
2257 conn, conn->smb1.echo_handler.trusted_fd);
2258 return;
2262 #ifdef CLUSTER_SUPPORT
2263 /****************************************************************************
2264 received when we should release a specific IP
2265 ****************************************************************************/
2266 static void release_ip(const char *ip, void *priv)
2268 const char *addr = (const char *)priv;
2269 const char *p = addr;
2271 if (strncmp("::ffff:", addr, 7) == 0) {
2272 p = addr + 7;
2275 DEBUG(10, ("Got release IP message for %s, "
2276 "our address is %s\n", ip, p));
2278 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2279 /* we can't afford to do a clean exit - that involves
2280 database writes, which would potentially mean we
2281 are still running after the failover has finished -
2282 we have to get rid of this process ID straight
2283 away */
2284 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2285 ip));
2286 /* note we must exit with non-zero status so the unclean handler gets
2287 called in the parent, so that the brl database is tickled */
2288 _exit(1);
2292 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2293 struct sockaddr_storage *client)
2295 socklen_t length;
2296 length = sizeof(*server);
2297 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2298 return -1;
2300 length = sizeof(*client);
2301 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2302 return -1;
2304 return 0;
2306 #endif
2309 * Send keepalive packets to our client
2311 static bool keepalive_fn(const struct timeval *now, void *private_data)
2313 struct smbd_server_connection *sconn = talloc_get_type_abort(
2314 private_data, struct smbd_server_connection);
2315 bool ret;
2317 if (sconn->using_smb2) {
2318 /* Don't do keepalives on an SMB2 connection. */
2319 return false;
2322 smbd_lock_socket(sconn);
2323 ret = send_keepalive(sconn->sock);
2324 smbd_unlock_socket(sconn);
2326 if (!ret) {
2327 char addr[INET6_ADDRSTRLEN];
2329 * Try and give an error message saying what
2330 * client failed.
2332 DEBUG(0, ("send_keepalive failed for client %s. "
2333 "Error %s - exiting\n",
2334 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2335 strerror(errno)));
2336 return False;
2338 return True;
2342 * Do the recurring check if we're idle
2344 static bool deadtime_fn(const struct timeval *now, void *private_data)
2346 struct smbd_server_connection *sconn =
2347 (struct smbd_server_connection *)private_data;
2349 if ((conn_num_open(sconn) == 0)
2350 || (conn_idle_all(sconn, now->tv_sec))) {
2351 DEBUG( 2, ( "Closing idle connection\n" ) );
2352 messaging_send(sconn->msg_ctx,
2353 messaging_server_id(sconn->msg_ctx),
2354 MSG_SHUTDOWN, &data_blob_null);
2355 return False;
2358 return True;
2362 * Do the recurring log file and smb.conf reload checks.
2365 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2367 struct smbd_server_connection *sconn = talloc_get_type_abort(
2368 private_data, struct smbd_server_connection);
2370 DEBUG(5, ("housekeeping\n"));
2372 change_to_root_user();
2374 /* update printer queue caches if necessary */
2375 update_monitored_printq_cache(sconn->msg_ctx);
2377 /* check if we need to reload services */
2378 check_reload(sconn, time_mono(NULL));
2380 /* Change machine password if neccessary. */
2381 attempt_machine_password_change();
2384 * Force a log file check.
2386 force_check_log_size();
2387 check_log_size();
2388 return true;
2392 * Read an smb packet in the echo handler child, giving the parent
2393 * smbd one second to react once the socket becomes readable.
2396 struct smbd_echo_read_state {
2397 struct tevent_context *ev;
2398 struct smbd_server_connection *sconn;
2400 char *buf;
2401 size_t buflen;
2402 uint32_t seqnum;
2405 static void smbd_echo_read_readable(struct tevent_req *subreq);
2406 static void smbd_echo_read_waited(struct tevent_req *subreq);
2408 static struct tevent_req *smbd_echo_read_send(
2409 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2410 struct smbd_server_connection *sconn)
2412 struct tevent_req *req, *subreq;
2413 struct smbd_echo_read_state *state;
2415 req = tevent_req_create(mem_ctx, &state,
2416 struct smbd_echo_read_state);
2417 if (req == NULL) {
2418 return NULL;
2420 state->ev = ev;
2421 state->sconn = sconn;
2423 subreq = wait_for_read_send(state, ev, sconn->sock);
2424 if (tevent_req_nomem(subreq, req)) {
2425 return tevent_req_post(req, ev);
2427 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2428 return req;
2431 static void smbd_echo_read_readable(struct tevent_req *subreq)
2433 struct tevent_req *req = tevent_req_callback_data(
2434 subreq, struct tevent_req);
2435 struct smbd_echo_read_state *state = tevent_req_data(
2436 req, struct smbd_echo_read_state);
2437 bool ok;
2438 int err;
2440 ok = wait_for_read_recv(subreq, &err);
2441 TALLOC_FREE(subreq);
2442 if (!ok) {
2443 tevent_req_nterror(req, map_nt_error_from_unix(err));
2444 return;
2448 * Give the parent smbd one second to step in
2451 subreq = tevent_wakeup_send(
2452 state, state->ev, timeval_current_ofs(1, 0));
2453 if (tevent_req_nomem(subreq, req)) {
2454 return;
2456 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2459 static void smbd_echo_read_waited(struct tevent_req *subreq)
2461 struct tevent_req *req = tevent_req_callback_data(
2462 subreq, struct tevent_req);
2463 struct smbd_echo_read_state *state = tevent_req_data(
2464 req, struct smbd_echo_read_state);
2465 struct smbd_server_connection *sconn = state->sconn;
2466 bool ok;
2467 NTSTATUS status;
2468 size_t unread = 0;
2469 bool encrypted;
2471 ok = tevent_wakeup_recv(subreq);
2472 TALLOC_FREE(subreq);
2473 if (!ok) {
2474 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2475 return;
2478 ok = smbd_lock_socket_internal(sconn);
2479 if (!ok) {
2480 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2481 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2482 return;
2485 if (!fd_is_readable(sconn->sock)) {
2486 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2487 (int)sys_getpid()));
2489 ok = smbd_unlock_socket_internal(sconn);
2490 if (!ok) {
2491 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2492 DEBUG(1, ("%s: failed to unlock socket\n",
2493 __location__));
2494 return;
2497 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2498 if (tevent_req_nomem(subreq, req)) {
2499 return;
2501 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2502 return;
2505 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2506 0 /* timeout */,
2507 &unread,
2508 &encrypted,
2509 &state->buflen,
2510 &state->seqnum,
2511 false /* trusted_channel*/);
2513 if (tevent_req_nterror(req, status)) {
2514 tevent_req_nterror(req, status);
2515 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2516 (int)sys_getpid(), nt_errstr(status)));
2517 return;
2520 ok = smbd_unlock_socket_internal(sconn);
2521 if (!ok) {
2522 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2523 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2524 return;
2526 tevent_req_done(req);
2529 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2530 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2532 struct smbd_echo_read_state *state = tevent_req_data(
2533 req, struct smbd_echo_read_state);
2534 NTSTATUS status;
2536 if (tevent_req_is_nterror(req, &status)) {
2537 return status;
2539 *pbuf = talloc_move(mem_ctx, &state->buf);
2540 *pbuflen = state->buflen;
2541 *pseqnum = state->seqnum;
2542 return NT_STATUS_OK;
2545 struct smbd_echo_state {
2546 struct tevent_context *ev;
2547 struct iovec *pending;
2548 struct smbd_server_connection *sconn;
2549 int parent_pipe;
2551 struct tevent_fd *parent_fde;
2553 struct tevent_req *write_req;
2556 static void smbd_echo_writer_done(struct tevent_req *req);
2558 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2560 int num_pending;
2562 if (state->write_req != NULL) {
2563 return;
2566 num_pending = talloc_array_length(state->pending);
2567 if (num_pending == 0) {
2568 return;
2571 state->write_req = writev_send(state, state->ev, NULL,
2572 state->parent_pipe, false,
2573 state->pending, num_pending);
2574 if (state->write_req == NULL) {
2575 DEBUG(1, ("writev_send failed\n"));
2576 exit(1);
2579 talloc_steal(state->write_req, state->pending);
2580 state->pending = NULL;
2582 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2583 state);
2586 static void smbd_echo_writer_done(struct tevent_req *req)
2588 struct smbd_echo_state *state = tevent_req_callback_data(
2589 req, struct smbd_echo_state);
2590 ssize_t written;
2591 int err;
2593 written = writev_recv(req, &err);
2594 TALLOC_FREE(req);
2595 state->write_req = NULL;
2596 if (written == -1) {
2597 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2598 exit(1);
2600 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2601 smbd_echo_activate_writer(state);
2604 static bool smbd_echo_reply(struct smbd_echo_state *state,
2605 uint8_t *inbuf, size_t inbuf_len,
2606 uint32_t seqnum)
2608 struct smb_request req;
2609 uint16_t num_replies;
2610 char *outbuf;
2611 bool ok;
2613 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2614 DEBUG(10, ("Got netbios keepalive\n"));
2616 * Just swallow it
2618 return true;
2621 if (inbuf_len < smb_size) {
2622 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2623 return false;
2625 if (!valid_smb_header(state->sconn, inbuf)) {
2626 DEBUG(10, ("Got invalid SMB header\n"));
2627 return false;
2630 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2631 seqnum)) {
2632 return false;
2634 req.inbuf = inbuf;
2636 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2637 smb_messages[req.cmd].name
2638 ? smb_messages[req.cmd].name : "unknown"));
2640 if (req.cmd != SMBecho) {
2641 return false;
2643 if (req.wct < 1) {
2644 return false;
2647 num_replies = SVAL(req.vwv+0, 0);
2648 if (num_replies != 1) {
2649 /* Not a Windows "Hey, you're still there?" request */
2650 return false;
2653 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2654 1, req.buflen)) {
2655 DEBUG(10, ("create_outbuf failed\n"));
2656 return false;
2658 req.outbuf = (uint8_t *)outbuf;
2660 SSVAL(req.outbuf, smb_vwv0, num_replies);
2662 if (req.buflen > 0) {
2663 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2666 ok = srv_send_smb(req.sconn,
2667 (char *)outbuf,
2668 true, seqnum+1,
2669 false, &req.pcd);
2670 TALLOC_FREE(outbuf);
2671 if (!ok) {
2672 exit(1);
2675 return true;
2678 static void smbd_echo_exit(struct tevent_context *ev,
2679 struct tevent_fd *fde, uint16_t flags,
2680 void *private_data)
2682 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2683 exit(0);
2686 static void smbd_echo_got_packet(struct tevent_req *req);
2688 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2689 int parent_pipe)
2691 struct smbd_echo_state *state;
2692 struct tevent_req *read_req;
2694 state = talloc_zero(sconn, struct smbd_echo_state);
2695 if (state == NULL) {
2696 DEBUG(1, ("talloc failed\n"));
2697 return;
2699 state->sconn = sconn;
2700 state->parent_pipe = parent_pipe;
2701 state->ev = s3_tevent_context_init(state);
2702 if (state->ev == NULL) {
2703 DEBUG(1, ("tevent_context_init failed\n"));
2704 TALLOC_FREE(state);
2705 return;
2707 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2708 TEVENT_FD_READ, smbd_echo_exit,
2709 state);
2710 if (state->parent_fde == NULL) {
2711 DEBUG(1, ("tevent_add_fd failed\n"));
2712 TALLOC_FREE(state);
2713 return;
2716 read_req = smbd_echo_read_send(state, state->ev, sconn);
2717 if (read_req == NULL) {
2718 DEBUG(1, ("smbd_echo_read_send failed\n"));
2719 TALLOC_FREE(state);
2720 return;
2722 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2724 while (true) {
2725 if (tevent_loop_once(state->ev) == -1) {
2726 DEBUG(1, ("tevent_loop_once failed: %s\n",
2727 strerror(errno)));
2728 break;
2731 TALLOC_FREE(state);
2734 static void smbd_echo_got_packet(struct tevent_req *req)
2736 struct smbd_echo_state *state = tevent_req_callback_data(
2737 req, struct smbd_echo_state);
2738 NTSTATUS status;
2739 char *buf = NULL;
2740 size_t buflen = 0;
2741 uint32_t seqnum = 0;
2742 bool reply;
2744 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2745 TALLOC_FREE(req);
2746 if (!NT_STATUS_IS_OK(status)) {
2747 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2748 nt_errstr(status)));
2749 exit(1);
2752 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2753 if (!reply) {
2754 size_t num_pending;
2755 struct iovec *tmp;
2756 struct iovec *iov;
2758 num_pending = talloc_array_length(state->pending);
2759 tmp = talloc_realloc(state, state->pending, struct iovec,
2760 num_pending+1);
2761 if (tmp == NULL) {
2762 DEBUG(1, ("talloc_realloc failed\n"));
2763 exit(1);
2765 state->pending = tmp;
2767 if (buflen >= smb_size) {
2769 * place the seqnum in the packet so that the main process
2770 * can reply with signing
2772 SIVAL(buf, smb_ss_field, seqnum);
2773 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2776 iov = &state->pending[num_pending];
2777 iov->iov_base = buf;
2778 iov->iov_len = buflen;
2780 DEBUG(10,("echo_handler[%d]: forward to main\n",
2781 (int)sys_getpid()));
2782 smbd_echo_activate_writer(state);
2785 req = smbd_echo_read_send(state, state->ev, state->sconn);
2786 if (req == NULL) {
2787 DEBUG(1, ("smbd_echo_read_send failed\n"));
2788 exit(1);
2790 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2795 * Handle SMBecho requests in a forked child process
2797 bool fork_echo_handler(struct smbd_server_connection *sconn)
2799 int listener_pipe[2];
2800 int res;
2801 pid_t child;
2803 res = pipe(listener_pipe);
2804 if (res == -1) {
2805 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2806 return false;
2808 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2809 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2810 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2811 goto fail;
2814 child = sys_fork();
2815 if (child == 0) {
2816 NTSTATUS status;
2818 close(listener_pipe[0]);
2819 set_blocking(listener_pipe[1], false);
2821 status = reinit_after_fork(sconn->msg_ctx,
2822 sconn->ev_ctx,
2823 false);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 DEBUG(1, ("reinit_after_fork failed: %s\n",
2826 nt_errstr(status)));
2827 exit(1);
2829 smbd_echo_loop(sconn, listener_pipe[1]);
2830 exit(0);
2832 close(listener_pipe[1]);
2833 listener_pipe[1] = -1;
2834 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2836 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2839 * Without smb signing this is the same as the normal smbd
2840 * listener. This needs to change once signing comes in.
2842 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2843 sconn,
2844 sconn->smb1.echo_handler.trusted_fd,
2845 TEVENT_FD_READ,
2846 smbd_server_echo_handler,
2847 sconn);
2848 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2849 DEBUG(1, ("event_add_fd failed\n"));
2850 goto fail;
2853 return true;
2855 fail:
2856 if (listener_pipe[0] != -1) {
2857 close(listener_pipe[0]);
2859 if (listener_pipe[1] != -1) {
2860 close(listener_pipe[1]);
2862 sconn->smb1.echo_handler.trusted_fd = -1;
2863 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2864 close(sconn->smb1.echo_handler.socket_lock_fd);
2866 sconn->smb1.echo_handler.trusted_fd = -1;
2867 sconn->smb1.echo_handler.socket_lock_fd = -1;
2868 return false;
2871 #if CLUSTER_SUPPORT
2873 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2874 struct sockaddr_storage *srv,
2875 struct sockaddr_storage *clnt)
2877 struct ctdbd_connection *cconn;
2878 char tmp_addr[INET6_ADDRSTRLEN];
2879 char *addr;
2881 cconn = messaging_ctdbd_connection();
2882 if (cconn == NULL) {
2883 return NT_STATUS_NO_MEMORY;
2886 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2887 addr = talloc_strdup(cconn, tmp_addr);
2888 if (addr == NULL) {
2889 return NT_STATUS_NO_MEMORY;
2891 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2894 #endif
2896 static bool uid_in_use(const struct user_struct *user, uid_t uid)
2898 while (user) {
2899 if (user->session_info &&
2900 (user->session_info->unix_token->uid == uid)) {
2901 return true;
2903 user = user->next;
2905 return false;
2908 static bool gid_in_use(const struct user_struct *user, gid_t gid)
2910 while (user) {
2911 if (user->session_info != NULL) {
2912 int i;
2913 struct security_unix_token *utok;
2915 utok = user->session_info->unix_token;
2916 if (utok->gid == gid) {
2917 return true;
2919 for(i=0; i<utok->ngroups; i++) {
2920 if (utok->groups[i] == gid) {
2921 return true;
2925 user = user->next;
2927 return false;
2930 static bool sid_in_use(const struct user_struct *user,
2931 const struct dom_sid *psid)
2933 while (user) {
2934 struct security_token *tok;
2936 if (user->session_info == NULL) {
2937 continue;
2939 tok = user->session_info->security_token;
2940 if (tok == NULL) {
2942 * Not sure session_info->security_token can
2943 * ever be NULL. This check might be not
2944 * necessary.
2946 continue;
2948 if (security_token_has_sid(tok, psid)) {
2949 return true;
2951 user = user->next;
2953 return false;
2956 static bool id_in_use(const struct user_struct *user,
2957 const struct id_cache_ref *id)
2959 switch(id->type) {
2960 case UID:
2961 return uid_in_use(user, id->id.uid);
2962 case GID:
2963 return gid_in_use(user, id->id.gid);
2964 case SID:
2965 return sid_in_use(user, &id->id.sid);
2966 default:
2967 break;
2969 return false;
2972 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
2973 void *private_data,
2974 uint32_t msg_type,
2975 struct server_id server_id,
2976 DATA_BLOB* data)
2978 const char *msg = (data && data->data)
2979 ? (const char *)data->data : "<NULL>";
2980 struct user_struct *validated_users;
2981 struct id_cache_ref id;
2982 struct smbd_server_connection *sconn =
2983 talloc_get_type_abort(private_data,
2984 struct smbd_server_connection);
2986 validated_users = sconn->smb1.sessions.validated_users;
2988 if (!id_cache_ref_parse(msg, &id)) {
2989 DEBUG(0, ("Invalid ?ID: %s\n", msg));
2990 return;
2993 if (id_in_use(validated_users, &id)) {
2994 exit_server_cleanly(msg);
2996 id_cache_delete_from_cache(&id);
2999 /****************************************************************************
3000 Process commands from the client
3001 ****************************************************************************/
3003 void smbd_process(struct tevent_context *ev_ctx,
3004 struct smbd_server_connection *sconn)
3006 TALLOC_CTX *frame = talloc_stackframe();
3007 struct sockaddr_storage ss;
3008 struct sockaddr *sa = NULL;
3009 socklen_t sa_socklen;
3010 struct tsocket_address *local_address = NULL;
3011 struct tsocket_address *remote_address = NULL;
3012 const char *locaddr = NULL;
3013 const char *remaddr = NULL;
3014 char *rhost;
3015 int ret;
3017 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3019 * We're not making the decision here,
3020 * we're just allowing the client
3021 * to decide between SMB1 and SMB2
3022 * with the first negprot
3023 * packet.
3025 sconn->using_smb2 = true;
3028 /* Ensure child is set to blocking mode */
3029 set_blocking(sconn->sock,True);
3031 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3032 set_socket_options(sconn->sock, lp_socket_options());
3034 sa = (struct sockaddr *)(void *)&ss;
3035 sa_socklen = sizeof(ss);
3036 ret = getpeername(sconn->sock, sa, &sa_socklen);
3037 if (ret != 0) {
3038 int level = (errno == ENOTCONN)?2:0;
3039 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3040 exit_server_cleanly("getpeername() failed.\n");
3042 ret = tsocket_address_bsd_from_sockaddr(sconn,
3043 sa, sa_socklen,
3044 &remote_address);
3045 if (ret != 0) {
3046 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3047 __location__, strerror(errno)));
3048 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3051 sa = (struct sockaddr *)(void *)&ss;
3052 sa_socklen = sizeof(ss);
3053 ret = getsockname(sconn->sock, sa, &sa_socklen);
3054 if (ret != 0) {
3055 int level = (errno == ENOTCONN)?2:0;
3056 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3057 exit_server_cleanly("getsockname() failed.\n");
3059 ret = tsocket_address_bsd_from_sockaddr(sconn,
3060 sa, sa_socklen,
3061 &local_address);
3062 if (ret != 0) {
3063 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3064 __location__, strerror(errno)));
3065 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3068 sconn->local_address = local_address;
3069 sconn->remote_address = remote_address;
3071 if (tsocket_address_is_inet(local_address, "ip")) {
3072 locaddr = tsocket_address_inet_addr_string(
3073 sconn->local_address,
3074 talloc_tos());
3075 if (locaddr == NULL) {
3076 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3077 __location__, strerror(errno)));
3078 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3080 } else {
3081 locaddr = "0.0.0.0";
3084 if (tsocket_address_is_inet(remote_address, "ip")) {
3085 remaddr = tsocket_address_inet_addr_string(
3086 sconn->remote_address,
3087 talloc_tos());
3088 if (remaddr == NULL) {
3089 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3090 __location__, strerror(errno)));
3091 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3093 } else {
3094 remaddr = "0.0.0.0";
3097 /* this is needed so that we get decent entries
3098 in smbstatus for port 445 connects */
3099 set_remote_machine_name(remaddr, false);
3100 reload_services(sconn, conn_snum_used, true);
3103 * Before the first packet, check the global hosts allow/ hosts deny
3104 * parameters before doing any parsing of packets passed to us by the
3105 * client. This prevents attacks on our parsing code from hosts not in
3106 * the hosts allow list.
3109 ret = get_remote_hostname(remote_address,
3110 &rhost,
3111 talloc_tos());
3112 if (ret < 0) {
3113 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3114 __location__, strerror(errno)));
3115 exit_server_cleanly("get_remote_hostname failed.\n");
3117 if (strequal(rhost, "UNKNOWN")) {
3118 rhost = talloc_strdup(talloc_tos(), remaddr);
3120 sconn->remote_hostname = talloc_move(sconn, &rhost);
3122 sub_set_socket_ids(remaddr,
3123 sconn->remote_hostname,
3124 locaddr);
3126 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3127 sconn->remote_hostname,
3128 remaddr)) {
3130 * send a negative session response "not listening on calling
3131 * name"
3133 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3134 DEBUG( 1, ("Connection denied from %s to %s\n",
3135 tsocket_address_string(remote_address, talloc_tos()),
3136 tsocket_address_string(local_address, talloc_tos())));
3137 (void)srv_send_smb(sconn,(char *)buf, false,
3138 0, false, NULL);
3139 exit_server_cleanly("connection denied");
3142 DEBUG(10, ("Connection allowed from %s to %s\n",
3143 tsocket_address_string(remote_address, talloc_tos()),
3144 tsocket_address_string(local_address, talloc_tos())));
3146 init_modules();
3148 smb_perfcount_init();
3150 if (!init_account_policy()) {
3151 exit_server("Could not open account policy tdb.\n");
3154 if (*lp_rootdir()) {
3155 if (chroot(lp_rootdir()) != 0) {
3156 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3157 exit_server("Failed to chroot()");
3159 if (chdir("/") == -1) {
3160 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3161 exit_server("Failed to chroot()");
3163 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3166 if (!srv_init_signing(sconn)) {
3167 exit_server("Failed to init smb_signing");
3170 /* Setup oplocks */
3171 if (!init_oplocks(sconn))
3172 exit_server("Failed to init oplocks");
3174 /* register our message handlers */
3175 messaging_register(sconn->msg_ctx, sconn,
3176 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3177 messaging_register(sconn->msg_ctx, sconn,
3178 MSG_SMB_CLOSE_FILE, msg_close_file);
3179 messaging_register(sconn->msg_ctx, sconn,
3180 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3182 id_cache_register_msgs(sconn->msg_ctx);
3183 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3184 messaging_register(sconn->msg_ctx, sconn,
3185 ID_CACHE_KILL, smbd_id_cache_kill);
3187 messaging_deregister(sconn->msg_ctx,
3188 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3189 messaging_register(sconn->msg_ctx, sconn,
3190 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3193 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3194 * MSGs to all child processes
3196 messaging_deregister(sconn->msg_ctx,
3197 MSG_DEBUG, NULL);
3198 messaging_register(sconn->msg_ctx, NULL,
3199 MSG_DEBUG, debug_message);
3201 if ((lp_keepalive() != 0)
3202 && !(event_add_idle(ev_ctx, NULL,
3203 timeval_set(lp_keepalive(), 0),
3204 "keepalive", keepalive_fn,
3205 sconn))) {
3206 DEBUG(0, ("Could not add keepalive event\n"));
3207 exit(1);
3210 if (!(event_add_idle(ev_ctx, NULL,
3211 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3212 "deadtime", deadtime_fn, sconn))) {
3213 DEBUG(0, ("Could not add deadtime event\n"));
3214 exit(1);
3217 if (!(event_add_idle(ev_ctx, NULL,
3218 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3219 "housekeeping", housekeeping_fn, sconn))) {
3220 DEBUG(0, ("Could not add housekeeping event\n"));
3221 exit(1);
3224 #ifdef CLUSTER_SUPPORT
3226 if (lp_clustering()) {
3228 * We need to tell ctdb about our client's TCP
3229 * connection, so that for failover ctdbd can send
3230 * tickle acks, triggering a reconnection by the
3231 * client.
3234 struct sockaddr_storage srv, clnt;
3236 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3237 NTSTATUS status;
3238 status = smbd_register_ips(sconn, &srv, &clnt);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3241 nt_errstr(status)));
3243 } else
3245 DEBUG(0,("Unable to get tcp info for "
3246 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3247 strerror(errno)));
3251 #endif
3253 sconn->nbt.got_session = false;
3255 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3257 sconn->smb1.sessions.done_sesssetup = false;
3258 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3259 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3260 /* this holds info on user ids that are already validated for this VC */
3261 sconn->smb1.sessions.validated_users = NULL;
3262 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3263 sconn->smb1.sessions.num_validated_vuids = 0;
3265 conn_init(sconn);
3266 if (!init_dptrs(sconn)) {
3267 exit_server("init_dptrs() failed");
3270 sconn->smb1.fde = event_add_fd(ev_ctx,
3271 sconn,
3272 sconn->sock,
3273 EVENT_FD_READ,
3274 smbd_server_connection_handler,
3275 sconn);
3276 if (!sconn->smb1.fde) {
3277 exit_server("failed to create smbd_server_connection fde");
3280 TALLOC_FREE(frame);
3282 while (True) {
3283 frame = talloc_stackframe_pool(8192);
3285 errno = 0;
3286 if (tevent_loop_once(ev_ctx) == -1) {
3287 if (errno != EINTR) {
3288 DEBUG(3, ("tevent_loop_once failed: %s,"
3289 " exiting\n", strerror(errno) ));
3290 break;
3294 TALLOC_FREE(frame);
3297 exit_server_cleanly(NULL);
3300 bool req_is_in_chain(struct smb_request *req)
3302 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3304 * We're right now handling a subsequent request, so we must
3305 * be in a chain
3307 return true;
3310 if (!is_andx_req(req->cmd)) {
3311 return false;
3314 if (req->wct < 2) {
3316 * Okay, an illegal request, but definitely not chained :-)
3318 return false;
3321 return (CVAL(req->vwv+0, 0) != 0xFF);