Replace smbd_server_connection_loop_once() with tevent_loop_once() directly.
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blob1d743552891a7b7b5799e3192ea3d135a34f6ccf
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 extern bool global_machine_password_needs_changing;
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct timed_event *te;
51 struct smb_perfcount_data pcd;
52 uint32_t seqnum;
53 bool encrypted;
54 bool processed;
55 DATA_BLOB buf;
56 DATA_BLOB private_data;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
60 char *outbuf);
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
66 bool ok;
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 return true;
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
75 return true;
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
83 SMB_F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
86 if (!ok) {
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 return false;
91 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
93 return true;
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
105 bool ok;
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 return true;
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
114 return true;
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
120 SMB_F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
123 if (!ok) {
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 return false;
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
130 return true;
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
143 Send an smb to a fd.
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
151 size_t len = 0;
152 size_t nwritten=0;
153 ssize_t ret;
154 char *buf_out = buffer;
156 smbd_lock_socket(sconn);
158 if (do_signing) {
159 /* Sign the outgoing packet if required. */
160 srv_calculate_sign_mac(sconn, buf_out, seqnum);
163 if (do_encrypt) {
164 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
165 if (!NT_STATUS_IS_OK(status)) {
166 DEBUG(0, ("send_smb: SMB encryption failed "
167 "on outgoing packet! Error %s\n",
168 nt_errstr(status) ));
169 goto out;
173 len = smb_len(buf_out) + 4;
175 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
176 if (ret <= 0) {
178 char addr[INET6_ADDRSTRLEN];
180 * Try and give an error message saying what
181 * client failed.
183 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
184 (int)sys_getpid(), (int)len,
185 get_peer_addr(sconn->sock, addr, sizeof(addr)),
186 (int)ret, strerror(errno) ));
188 srv_free_enc_buffer(sconn, buf_out);
189 goto out;
192 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
193 srv_free_enc_buffer(sconn, buf_out);
194 out:
195 SMB_PERFCOUNT_END(pcd);
197 smbd_unlock_socket(sconn);
198 return true;
201 /*******************************************************************
202 Setup the word count and byte count for a smb message.
203 ********************************************************************/
205 int srv_set_message(char *buf,
206 int num_words,
207 int num_bytes,
208 bool zero)
210 if (zero && (num_words || num_bytes)) {
211 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
213 SCVAL(buf,smb_wct,num_words);
214 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
215 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
216 return (smb_size + num_words*2 + num_bytes);
219 static bool valid_smb_header(struct smbd_server_connection *sconn,
220 const uint8_t *inbuf)
222 if (is_encrypted_packet(sconn, inbuf)) {
223 return true;
226 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
227 * but it just looks weird to call strncmp for this one.
229 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
232 /* Socket functions for smbd packet processing. */
234 static bool valid_packet_size(size_t len)
237 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
238 * of header. Don't print the error if this fits.... JRA.
241 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
242 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
243 (unsigned long)len));
244 return false;
246 return true;
249 static NTSTATUS read_packet_remainder(int fd, char *buffer,
250 unsigned int timeout, ssize_t len)
252 NTSTATUS status;
254 if (len <= 0) {
255 return NT_STATUS_OK;
258 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
259 if (!NT_STATUS_IS_OK(status)) {
260 char addr[INET6_ADDRSTRLEN];
261 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
262 "error = %s.\n",
263 get_peer_addr(fd, addr, sizeof(addr)),
264 nt_errstr(status)));
266 return status;
269 /****************************************************************************
270 Attempt a zerocopy writeX read. We know here that len > smb_size-4
271 ****************************************************************************/
274 * Unfortunately, earlier versions of smbclient/libsmbclient
275 * don't send this "standard" writeX header. I've fixed this
276 * for 3.2 but we'll use the old method with earlier versions.
277 * Windows and CIFSFS at least use this standard size. Not
278 * sure about MacOSX.
281 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
282 (2*14) + /* word count (including bcc) */ \
283 1 /* pad byte */)
285 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
286 const char lenbuf[4],
287 struct smbd_server_connection *sconn,
288 int sock,
289 char **buffer,
290 unsigned int timeout,
291 size_t *p_unread,
292 size_t *len_ret)
294 /* Size of a WRITEX call (+4 byte len). */
295 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
296 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
297 ssize_t toread;
298 NTSTATUS status;
300 memcpy(writeX_header, lenbuf, 4);
302 status = read_fd_with_timeout(
303 sock, writeX_header + 4,
304 STANDARD_WRITE_AND_X_HEADER_SIZE,
305 STANDARD_WRITE_AND_X_HEADER_SIZE,
306 timeout, NULL);
308 if (!NT_STATUS_IS_OK(status)) {
309 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
310 "error = %s.\n",
311 tsocket_address_string(sconn->remote_address,
312 talloc_tos()),
313 nt_errstr(status)));
314 return status;
318 * Ok - now try and see if this is a possible
319 * valid writeX call.
322 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
324 * If the data offset is beyond what
325 * we've read, drain the extra bytes.
327 uint16_t doff = SVAL(writeX_header,smb_vwv11);
328 ssize_t newlen;
330 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
331 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
332 if (drain_socket(sock, drain) != drain) {
333 smb_panic("receive_smb_raw_talloc_partial_read:"
334 " failed to drain pending bytes");
336 } else {
337 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
340 /* Spoof down the length and null out the bcc. */
341 set_message_bcc(writeX_header, 0);
342 newlen = smb_len(writeX_header);
344 /* Copy the header we've written. */
346 *buffer = (char *)talloc_memdup(mem_ctx,
347 writeX_header,
348 sizeof(writeX_header));
350 if (*buffer == NULL) {
351 DEBUG(0, ("Could not allocate inbuf of length %d\n",
352 (int)sizeof(writeX_header)));
353 return NT_STATUS_NO_MEMORY;
356 /* Work out the remaining bytes. */
357 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
358 *len_ret = newlen + 4;
359 return NT_STATUS_OK;
362 if (!valid_packet_size(len)) {
363 return NT_STATUS_INVALID_PARAMETER;
367 * Not a valid writeX call. Just do the standard
368 * talloc and return.
371 *buffer = talloc_array(mem_ctx, char, len+4);
373 if (*buffer == NULL) {
374 DEBUG(0, ("Could not allocate inbuf of length %d\n",
375 (int)len+4));
376 return NT_STATUS_NO_MEMORY;
379 /* Copy in what we already read. */
380 memcpy(*buffer,
381 writeX_header,
382 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
383 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
385 if(toread > 0) {
386 status = read_packet_remainder(
387 sock,
388 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
389 timeout, toread);
391 if (!NT_STATUS_IS_OK(status)) {
392 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
393 nt_errstr(status)));
394 return status;
398 *len_ret = len + 4;
399 return NT_STATUS_OK;
402 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
403 struct smbd_server_connection *sconn,
404 int sock,
405 char **buffer, unsigned int timeout,
406 size_t *p_unread, size_t *plen)
408 char lenbuf[4];
409 size_t len;
410 int min_recv_size = lp_min_receive_file_size();
411 NTSTATUS status;
413 *p_unread = 0;
415 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
416 &len);
417 if (!NT_STATUS_IS_OK(status)) {
418 return status;
421 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
422 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
423 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
424 !srv_is_signing_active(sconn) &&
425 sconn->smb1.echo_handler.trusted_fde == NULL) {
427 return receive_smb_raw_talloc_partial_read(
428 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
429 p_unread, plen);
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * The +4 here can't wrap, we've checked the length above already.
440 *buffer = talloc_array(mem_ctx, char, len+4);
442 if (*buffer == NULL) {
443 DEBUG(0, ("Could not allocate inbuf of length %d\n",
444 (int)len+4));
445 return NT_STATUS_NO_MEMORY;
448 memcpy(*buffer, lenbuf, sizeof(lenbuf));
450 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
451 if (!NT_STATUS_IS_OK(status)) {
452 return status;
455 *plen = len + 4;
456 return NT_STATUS_OK;
459 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
460 struct smbd_server_connection *sconn,
461 int sock,
462 char **buffer, unsigned int timeout,
463 size_t *p_unread, bool *p_encrypted,
464 size_t *p_len,
465 uint32_t *seqnum,
466 bool trusted_channel)
468 size_t len = 0;
469 NTSTATUS status;
471 *p_encrypted = false;
473 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
474 p_unread, &len);
475 if (!NT_STATUS_IS_OK(status)) {
476 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
477 ("receive_smb_raw_talloc failed for client %s "
478 "read error = %s.\n",
479 tsocket_address_string(sconn->remote_address,
480 talloc_tos()),
481 nt_errstr(status)) );
482 return status;
485 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
486 status = srv_decrypt_buffer(sconn, *buffer);
487 if (!NT_STATUS_IS_OK(status)) {
488 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
489 "incoming packet! Error %s\n",
490 nt_errstr(status) ));
491 return status;
493 *p_encrypted = true;
496 /* Check the incoming SMB signature. */
497 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
498 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
499 "incoming packet!\n"));
500 return NT_STATUS_INVALID_NETWORK_RESPONSE;
503 *p_len = len;
504 return NT_STATUS_OK;
508 * Initialize a struct smb_request from an inbuf
511 static bool init_smb_request(struct smb_request *req,
512 struct smbd_server_connection *sconn,
513 const uint8 *inbuf,
514 size_t unread_bytes, bool encrypted,
515 uint32_t seqnum)
517 size_t req_size = smb_len(inbuf) + 4;
518 /* Ensure we have at least smb_size bytes. */
519 if (req_size < smb_size) {
520 DEBUG(0,("init_smb_request: invalid request size %u\n",
521 (unsigned int)req_size ));
522 return false;
524 req->cmd = CVAL(inbuf, smb_com);
525 req->flags2 = SVAL(inbuf, smb_flg2);
526 req->smbpid = SVAL(inbuf, smb_pid);
527 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
528 req->seqnum = seqnum;
529 req->vuid = SVAL(inbuf, smb_uid);
530 req->tid = SVAL(inbuf, smb_tid);
531 req->wct = CVAL(inbuf, smb_wct);
532 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
533 req->buflen = smb_buflen(inbuf);
534 req->buf = (const uint8_t *)smb_buf_const(inbuf);
535 req->unread_bytes = unread_bytes;
536 req->encrypted = encrypted;
537 req->sconn = sconn;
538 req->conn = conn_find(sconn,req->tid);
539 req->chain_fsp = NULL;
540 req->chain_outbuf = NULL;
541 req->done = false;
542 req->smb2req = NULL;
543 smb_init_perfcount_data(&req->pcd);
545 /* Ensure we have at least wct words and 2 bytes of bcc. */
546 if (smb_size + req->wct*2 > req_size) {
547 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
548 (unsigned int)req->wct,
549 (unsigned int)req_size));
550 return false;
552 /* Ensure bcc is correct. */
553 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
554 DEBUG(0,("init_smb_request: invalid bcc number %u "
555 "(wct = %u, size %u)\n",
556 (unsigned int)req->buflen,
557 (unsigned int)req->wct,
558 (unsigned int)req_size));
559 return false;
562 req->outbuf = NULL;
563 return true;
566 static void process_smb(struct smbd_server_connection *conn,
567 uint8_t *inbuf, size_t nread, size_t unread_bytes,
568 uint32_t seqnum, bool encrypted,
569 struct smb_perfcount_data *deferred_pcd);
571 static void smbd_deferred_open_timer(struct event_context *ev,
572 struct timed_event *te,
573 struct timeval _tval,
574 void *private_data)
576 struct pending_message_list *msg = talloc_get_type(private_data,
577 struct pending_message_list);
578 struct smbd_server_connection *sconn = msg->sconn;
579 TALLOC_CTX *mem_ctx = talloc_tos();
580 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
581 uint8_t *inbuf;
583 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
584 msg->buf.length);
585 if (inbuf == NULL) {
586 exit_server("smbd_deferred_open_timer: talloc failed\n");
587 return;
590 /* We leave this message on the queue so the open code can
591 know this is a retry. */
592 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
593 (unsigned long long)mid ));
595 /* Mark the message as processed so this is not
596 * re-processed in error. */
597 msg->processed = true;
599 process_smb(sconn, inbuf,
600 msg->buf.length, 0,
601 msg->seqnum, msg->encrypted, &msg->pcd);
603 /* If it's still there and was processed, remove it. */
604 msg = get_deferred_open_message_smb(sconn, mid);
605 if (msg && msg->processed) {
606 remove_deferred_open_message_smb(sconn, mid);
610 /****************************************************************************
611 Function to push a message onto the tail of a linked list of smb messages ready
612 for processing.
613 ****************************************************************************/
615 static bool push_queued_message(struct smb_request *req,
616 struct timeval request_time,
617 struct timeval end_time,
618 char *private_data, size_t private_len)
620 int msg_len = smb_len(req->inbuf) + 4;
621 struct pending_message_list *msg;
623 msg = talloc_zero(NULL, struct pending_message_list);
625 if(msg == NULL) {
626 DEBUG(0,("push_message: malloc fail (1)\n"));
627 return False;
629 msg->sconn = req->sconn;
631 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
632 if(msg->buf.data == NULL) {
633 DEBUG(0,("push_message: malloc fail (2)\n"));
634 TALLOC_FREE(msg);
635 return False;
638 msg->request_time = request_time;
639 msg->seqnum = req->seqnum;
640 msg->encrypted = req->encrypted;
641 msg->processed = false;
642 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
644 if (private_data) {
645 msg->private_data = data_blob_talloc(msg, private_data,
646 private_len);
647 if (msg->private_data.data == NULL) {
648 DEBUG(0,("push_message: malloc fail (3)\n"));
649 TALLOC_FREE(msg);
650 return False;
654 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
655 msg,
656 end_time,
657 smbd_deferred_open_timer,
658 msg);
659 if (!msg->te) {
660 DEBUG(0,("push_message: event_add_timed failed\n"));
661 TALLOC_FREE(msg);
662 return false;
665 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
666 struct pending_message_list *);
668 DEBUG(10,("push_message: pushed message length %u on "
669 "deferred_open_queue\n", (unsigned int)msg_len));
671 return True;
674 /****************************************************************************
675 Function to delete a sharing violation open message by mid.
676 ****************************************************************************/
678 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
679 uint64_t mid)
681 struct pending_message_list *pml;
683 if (sconn->using_smb2) {
684 remove_deferred_open_message_smb2(sconn, mid);
685 return;
688 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
689 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
690 DEBUG(10,("remove_deferred_open_message_smb: "
691 "deleting mid %llu len %u\n",
692 (unsigned long long)mid,
693 (unsigned int)pml->buf.length ));
694 DLIST_REMOVE(sconn->deferred_open_queue, pml);
695 TALLOC_FREE(pml);
696 return;
701 /****************************************************************************
702 Move a sharing violation open retry message to the front of the list and
703 schedule it for immediate processing.
704 ****************************************************************************/
706 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
707 uint64_t mid)
709 struct pending_message_list *pml;
710 int i = 0;
712 if (sconn->using_smb2) {
713 schedule_deferred_open_message_smb2(sconn, mid);
714 return;
717 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
718 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
720 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
721 "msg_mid = %llu\n",
722 i++,
723 (unsigned long long)msg_mid ));
725 if (mid == msg_mid) {
726 struct timed_event *te;
728 if (pml->processed) {
729 /* A processed message should not be
730 * rescheduled. */
731 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
732 "message mid %llu was already processed\n",
733 (unsigned long long)msg_mid ));
734 continue;
737 DEBUG(10,("schedule_deferred_open_message_smb: "
738 "scheduling mid %llu\n",
739 (unsigned long long)mid ));
741 te = tevent_add_timer(pml->sconn->ev_ctx,
742 pml,
743 timeval_zero(),
744 smbd_deferred_open_timer,
745 pml);
746 if (!te) {
747 DEBUG(10,("schedule_deferred_open_message_smb: "
748 "event_add_timed() failed, "
749 "skipping mid %llu\n",
750 (unsigned long long)msg_mid ));
753 TALLOC_FREE(pml->te);
754 pml->te = te;
755 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
756 return;
760 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
761 "find message mid %llu\n",
762 (unsigned long long)mid ));
765 /****************************************************************************
766 Return true if this mid is on the deferred queue and was not yet processed.
767 ****************************************************************************/
769 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
771 struct pending_message_list *pml;
773 if (sconn->using_smb2) {
774 return open_was_deferred_smb2(sconn, mid);
777 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
778 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
779 return True;
782 return False;
785 /****************************************************************************
786 Return the message queued by this mid.
787 ****************************************************************************/
789 static struct pending_message_list *get_deferred_open_message_smb(
790 struct smbd_server_connection *sconn, uint64_t mid)
792 struct pending_message_list *pml;
794 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
795 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
796 return pml;
799 return NULL;
802 /****************************************************************************
803 Get the state data queued by this mid.
804 ****************************************************************************/
806 bool get_deferred_open_message_state(struct smb_request *smbreq,
807 struct timeval *p_request_time,
808 void **pp_state)
810 struct pending_message_list *pml;
812 if (smbreq->sconn->using_smb2) {
813 return get_deferred_open_message_state_smb2(smbreq->smb2req,
814 p_request_time,
815 pp_state);
818 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
819 if (!pml) {
820 return false;
822 if (p_request_time) {
823 *p_request_time = pml->request_time;
825 if (pp_state) {
826 *pp_state = (void *)pml->private_data.data;
828 return true;
831 /****************************************************************************
832 Function to push a deferred open smb message onto a linked list of local smb
833 messages ready for processing.
834 ****************************************************************************/
836 bool push_deferred_open_message_smb(struct smb_request *req,
837 struct timeval request_time,
838 struct timeval timeout,
839 struct file_id id,
840 char *private_data, size_t priv_len)
842 struct timeval end_time;
844 if (req->smb2req) {
845 return push_deferred_open_message_smb2(req->smb2req,
846 request_time,
847 timeout,
849 private_data,
850 priv_len);
853 if (req->unread_bytes) {
854 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
855 "unread_bytes = %u\n",
856 (unsigned int)req->unread_bytes ));
857 smb_panic("push_deferred_open_message_smb: "
858 "logic error unread_bytes != 0" );
861 end_time = timeval_sum(&request_time, &timeout);
863 DEBUG(10,("push_deferred_open_message_smb: pushing message "
864 "len %u mid %llu timeout time [%u.%06u]\n",
865 (unsigned int) smb_len(req->inbuf)+4,
866 (unsigned long long)req->mid,
867 (unsigned int)end_time.tv_sec,
868 (unsigned int)end_time.tv_usec));
870 return push_queued_message(req, request_time, end_time,
871 private_data, priv_len);
874 static void smbd_sig_term_handler(struct tevent_context *ev,
875 struct tevent_signal *se,
876 int signum,
877 int count,
878 void *siginfo,
879 void *private_data)
881 exit_server_cleanly("termination signal");
884 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
886 struct tevent_signal *se;
888 se = tevent_add_signal(sconn->ev_ctx,
889 sconn,
890 SIGTERM, 0,
891 smbd_sig_term_handler,
892 sconn);
893 if (!se) {
894 exit_server("failed to setup SIGTERM handler");
898 static void smbd_sig_hup_handler(struct tevent_context *ev,
899 struct tevent_signal *se,
900 int signum,
901 int count,
902 void *siginfo,
903 void *private_data)
905 struct smbd_server_connection *sconn =
906 talloc_get_type_abort(private_data,
907 struct smbd_server_connection);
909 change_to_root_user();
910 DEBUG(1,("Reloading services after SIGHUP\n"));
911 reload_services(sconn, conn_snum_used, false);
914 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
916 struct tevent_signal *se;
918 se = tevent_add_signal(sconn->ev_ctx,
919 sconn,
920 SIGHUP, 0,
921 smbd_sig_hup_handler,
922 sconn);
923 if (!se) {
924 exit_server("failed to setup SIGHUP handler");
928 static void smbd_conf_updated(struct messaging_context *msg,
929 void *private_data,
930 uint32_t msg_type,
931 struct server_id server_id,
932 DATA_BLOB *data)
934 struct smbd_server_connection *sconn =
935 talloc_get_type_abort(private_data,
936 struct smbd_server_connection);
938 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
939 "updated. Reloading.\n"));
940 change_to_root_user();
941 reload_services(sconn, conn_snum_used, false);
945 * Only allow 5 outstanding trans requests. We're allocating memory, so
946 * prevent a DoS.
949 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
951 int count = 0;
952 for (; list != NULL; list = list->next) {
954 if (list->mid == mid) {
955 return NT_STATUS_INVALID_PARAMETER;
958 count += 1;
960 if (count > 5) {
961 return NT_STATUS_INSUFFICIENT_RESOURCES;
964 return NT_STATUS_OK;
968 These flags determine some of the permissions required to do an operation
970 Note that I don't set NEED_WRITE on some write operations because they
971 are used by some brain-dead clients when printing, and I don't want to
972 force write permissions on print services.
974 #define AS_USER (1<<0)
975 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
976 #define TIME_INIT (1<<2)
977 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
978 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
979 #define DO_CHDIR (1<<6)
982 define a list of possible SMB messages and their corresponding
983 functions. Any message that has a NULL function is unimplemented -
984 please feel free to contribute implementations!
986 static const struct smb_message_struct {
987 const char *name;
988 void (*fn)(struct smb_request *req);
989 int flags;
990 } smb_messages[256] = {
992 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
993 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
994 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
995 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
996 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
997 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
998 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
999 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1000 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1001 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1002 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1003 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1004 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1005 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1006 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1007 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1008 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1009 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1010 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1011 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1012 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1013 /* 0x15 */ { NULL, NULL, 0 },
1014 /* 0x16 */ { NULL, NULL, 0 },
1015 /* 0x17 */ { NULL, NULL, 0 },
1016 /* 0x18 */ { NULL, NULL, 0 },
1017 /* 0x19 */ { NULL, NULL, 0 },
1018 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1019 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1020 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1021 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1022 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1023 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1024 /* 0x20 */ { "SMBwritec", NULL,0},
1025 /* 0x21 */ { NULL, NULL, 0 },
1026 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1027 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1028 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1029 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1030 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1031 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1032 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1033 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1034 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1035 /* 0x2b */ { "SMBecho",reply_echo,0},
1036 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1037 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1038 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1039 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1040 /* 0x30 */ { NULL, NULL, 0 },
1041 /* 0x31 */ { NULL, NULL, 0 },
1042 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1043 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1044 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1045 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1046 /* 0x36 */ { NULL, NULL, 0 },
1047 /* 0x37 */ { NULL, NULL, 0 },
1048 /* 0x38 */ { NULL, NULL, 0 },
1049 /* 0x39 */ { NULL, NULL, 0 },
1050 /* 0x3a */ { NULL, NULL, 0 },
1051 /* 0x3b */ { NULL, NULL, 0 },
1052 /* 0x3c */ { NULL, NULL, 0 },
1053 /* 0x3d */ { NULL, NULL, 0 },
1054 /* 0x3e */ { NULL, NULL, 0 },
1055 /* 0x3f */ { NULL, NULL, 0 },
1056 /* 0x40 */ { NULL, NULL, 0 },
1057 /* 0x41 */ { NULL, NULL, 0 },
1058 /* 0x42 */ { NULL, NULL, 0 },
1059 /* 0x43 */ { NULL, NULL, 0 },
1060 /* 0x44 */ { NULL, NULL, 0 },
1061 /* 0x45 */ { NULL, NULL, 0 },
1062 /* 0x46 */ { NULL, NULL, 0 },
1063 /* 0x47 */ { NULL, NULL, 0 },
1064 /* 0x48 */ { NULL, NULL, 0 },
1065 /* 0x49 */ { NULL, NULL, 0 },
1066 /* 0x4a */ { NULL, NULL, 0 },
1067 /* 0x4b */ { NULL, NULL, 0 },
1068 /* 0x4c */ { NULL, NULL, 0 },
1069 /* 0x4d */ { NULL, NULL, 0 },
1070 /* 0x4e */ { NULL, NULL, 0 },
1071 /* 0x4f */ { NULL, NULL, 0 },
1072 /* 0x50 */ { NULL, NULL, 0 },
1073 /* 0x51 */ { NULL, NULL, 0 },
1074 /* 0x52 */ { NULL, NULL, 0 },
1075 /* 0x53 */ { NULL, NULL, 0 },
1076 /* 0x54 */ { NULL, NULL, 0 },
1077 /* 0x55 */ { NULL, NULL, 0 },
1078 /* 0x56 */ { NULL, NULL, 0 },
1079 /* 0x57 */ { NULL, NULL, 0 },
1080 /* 0x58 */ { NULL, NULL, 0 },
1081 /* 0x59 */ { NULL, NULL, 0 },
1082 /* 0x5a */ { NULL, NULL, 0 },
1083 /* 0x5b */ { NULL, NULL, 0 },
1084 /* 0x5c */ { NULL, NULL, 0 },
1085 /* 0x5d */ { NULL, NULL, 0 },
1086 /* 0x5e */ { NULL, NULL, 0 },
1087 /* 0x5f */ { NULL, NULL, 0 },
1088 /* 0x60 */ { NULL, NULL, 0 },
1089 /* 0x61 */ { NULL, NULL, 0 },
1090 /* 0x62 */ { NULL, NULL, 0 },
1091 /* 0x63 */ { NULL, NULL, 0 },
1092 /* 0x64 */ { NULL, NULL, 0 },
1093 /* 0x65 */ { NULL, NULL, 0 },
1094 /* 0x66 */ { NULL, NULL, 0 },
1095 /* 0x67 */ { NULL, NULL, 0 },
1096 /* 0x68 */ { NULL, NULL, 0 },
1097 /* 0x69 */ { NULL, NULL, 0 },
1098 /* 0x6a */ { NULL, NULL, 0 },
1099 /* 0x6b */ { NULL, NULL, 0 },
1100 /* 0x6c */ { NULL, NULL, 0 },
1101 /* 0x6d */ { NULL, NULL, 0 },
1102 /* 0x6e */ { NULL, NULL, 0 },
1103 /* 0x6f */ { NULL, NULL, 0 },
1104 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1105 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1106 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1107 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1108 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1109 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1110 /* 0x76 */ { NULL, NULL, 0 },
1111 /* 0x77 */ { NULL, NULL, 0 },
1112 /* 0x78 */ { NULL, NULL, 0 },
1113 /* 0x79 */ { NULL, NULL, 0 },
1114 /* 0x7a */ { NULL, NULL, 0 },
1115 /* 0x7b */ { NULL, NULL, 0 },
1116 /* 0x7c */ { NULL, NULL, 0 },
1117 /* 0x7d */ { NULL, NULL, 0 },
1118 /* 0x7e */ { NULL, NULL, 0 },
1119 /* 0x7f */ { NULL, NULL, 0 },
1120 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1121 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1122 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1123 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1124 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1125 /* 0x85 */ { NULL, NULL, 0 },
1126 /* 0x86 */ { NULL, NULL, 0 },
1127 /* 0x87 */ { NULL, NULL, 0 },
1128 /* 0x88 */ { NULL, NULL, 0 },
1129 /* 0x89 */ { NULL, NULL, 0 },
1130 /* 0x8a */ { NULL, NULL, 0 },
1131 /* 0x8b */ { NULL, NULL, 0 },
1132 /* 0x8c */ { NULL, NULL, 0 },
1133 /* 0x8d */ { NULL, NULL, 0 },
1134 /* 0x8e */ { NULL, NULL, 0 },
1135 /* 0x8f */ { NULL, NULL, 0 },
1136 /* 0x90 */ { NULL, NULL, 0 },
1137 /* 0x91 */ { NULL, NULL, 0 },
1138 /* 0x92 */ { NULL, NULL, 0 },
1139 /* 0x93 */ { NULL, NULL, 0 },
1140 /* 0x94 */ { NULL, NULL, 0 },
1141 /* 0x95 */ { NULL, NULL, 0 },
1142 /* 0x96 */ { NULL, NULL, 0 },
1143 /* 0x97 */ { NULL, NULL, 0 },
1144 /* 0x98 */ { NULL, NULL, 0 },
1145 /* 0x99 */ { NULL, NULL, 0 },
1146 /* 0x9a */ { NULL, NULL, 0 },
1147 /* 0x9b */ { NULL, NULL, 0 },
1148 /* 0x9c */ { NULL, NULL, 0 },
1149 /* 0x9d */ { NULL, NULL, 0 },
1150 /* 0x9e */ { NULL, NULL, 0 },
1151 /* 0x9f */ { NULL, NULL, 0 },
1152 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1153 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1154 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1155 /* 0xa3 */ { NULL, NULL, 0 },
1156 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1157 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1158 /* 0xa6 */ { NULL, NULL, 0 },
1159 /* 0xa7 */ { NULL, NULL, 0 },
1160 /* 0xa8 */ { NULL, NULL, 0 },
1161 /* 0xa9 */ { NULL, NULL, 0 },
1162 /* 0xaa */ { NULL, NULL, 0 },
1163 /* 0xab */ { NULL, NULL, 0 },
1164 /* 0xac */ { NULL, NULL, 0 },
1165 /* 0xad */ { NULL, NULL, 0 },
1166 /* 0xae */ { NULL, NULL, 0 },
1167 /* 0xaf */ { NULL, NULL, 0 },
1168 /* 0xb0 */ { NULL, NULL, 0 },
1169 /* 0xb1 */ { NULL, NULL, 0 },
1170 /* 0xb2 */ { NULL, NULL, 0 },
1171 /* 0xb3 */ { NULL, NULL, 0 },
1172 /* 0xb4 */ { NULL, NULL, 0 },
1173 /* 0xb5 */ { NULL, NULL, 0 },
1174 /* 0xb6 */ { NULL, NULL, 0 },
1175 /* 0xb7 */ { NULL, NULL, 0 },
1176 /* 0xb8 */ { NULL, NULL, 0 },
1177 /* 0xb9 */ { NULL, NULL, 0 },
1178 /* 0xba */ { NULL, NULL, 0 },
1179 /* 0xbb */ { NULL, NULL, 0 },
1180 /* 0xbc */ { NULL, NULL, 0 },
1181 /* 0xbd */ { NULL, NULL, 0 },
1182 /* 0xbe */ { NULL, NULL, 0 },
1183 /* 0xbf */ { NULL, NULL, 0 },
1184 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1185 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1186 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1187 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1188 /* 0xc4 */ { NULL, NULL, 0 },
1189 /* 0xc5 */ { NULL, NULL, 0 },
1190 /* 0xc6 */ { NULL, NULL, 0 },
1191 /* 0xc7 */ { NULL, NULL, 0 },
1192 /* 0xc8 */ { NULL, NULL, 0 },
1193 /* 0xc9 */ { NULL, NULL, 0 },
1194 /* 0xca */ { NULL, NULL, 0 },
1195 /* 0xcb */ { NULL, NULL, 0 },
1196 /* 0xcc */ { NULL, NULL, 0 },
1197 /* 0xcd */ { NULL, NULL, 0 },
1198 /* 0xce */ { NULL, NULL, 0 },
1199 /* 0xcf */ { NULL, NULL, 0 },
1200 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1201 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1202 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1203 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1204 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1205 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1206 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1207 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1208 /* 0xd8 */ { NULL, NULL, 0 },
1209 /* 0xd9 */ { NULL, NULL, 0 },
1210 /* 0xda */ { NULL, NULL, 0 },
1211 /* 0xdb */ { NULL, NULL, 0 },
1212 /* 0xdc */ { NULL, NULL, 0 },
1213 /* 0xdd */ { NULL, NULL, 0 },
1214 /* 0xde */ { NULL, NULL, 0 },
1215 /* 0xdf */ { NULL, NULL, 0 },
1216 /* 0xe0 */ { NULL, NULL, 0 },
1217 /* 0xe1 */ { NULL, NULL, 0 },
1218 /* 0xe2 */ { NULL, NULL, 0 },
1219 /* 0xe3 */ { NULL, NULL, 0 },
1220 /* 0xe4 */ { NULL, NULL, 0 },
1221 /* 0xe5 */ { NULL, NULL, 0 },
1222 /* 0xe6 */ { NULL, NULL, 0 },
1223 /* 0xe7 */ { NULL, NULL, 0 },
1224 /* 0xe8 */ { NULL, NULL, 0 },
1225 /* 0xe9 */ { NULL, NULL, 0 },
1226 /* 0xea */ { NULL, NULL, 0 },
1227 /* 0xeb */ { NULL, NULL, 0 },
1228 /* 0xec */ { NULL, NULL, 0 },
1229 /* 0xed */ { NULL, NULL, 0 },
1230 /* 0xee */ { NULL, NULL, 0 },
1231 /* 0xef */ { NULL, NULL, 0 },
1232 /* 0xf0 */ { NULL, NULL, 0 },
1233 /* 0xf1 */ { NULL, NULL, 0 },
1234 /* 0xf2 */ { NULL, NULL, 0 },
1235 /* 0xf3 */ { NULL, NULL, 0 },
1236 /* 0xf4 */ { NULL, NULL, 0 },
1237 /* 0xf5 */ { NULL, NULL, 0 },
1238 /* 0xf6 */ { NULL, NULL, 0 },
1239 /* 0xf7 */ { NULL, NULL, 0 },
1240 /* 0xf8 */ { NULL, NULL, 0 },
1241 /* 0xf9 */ { NULL, NULL, 0 },
1242 /* 0xfa */ { NULL, NULL, 0 },
1243 /* 0xfb */ { NULL, NULL, 0 },
1244 /* 0xfc */ { NULL, NULL, 0 },
1245 /* 0xfd */ { NULL, NULL, 0 },
1246 /* 0xfe */ { NULL, NULL, 0 },
1247 /* 0xff */ { NULL, NULL, 0 }
1251 /*******************************************************************
1252 allocate and initialize a reply packet
1253 ********************************************************************/
1255 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1256 const char *inbuf, char **outbuf, uint8_t num_words,
1257 uint32_t num_bytes)
1260 * Protect against integer wrap
1262 if ((num_bytes > 0xffffff)
1263 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1264 char *msg;
1265 if (asprintf(&msg, "num_bytes too large: %u",
1266 (unsigned)num_bytes) == -1) {
1267 msg = discard_const_p(char, "num_bytes too large");
1269 smb_panic(msg);
1272 *outbuf = talloc_array(mem_ctx, char,
1273 smb_size + num_words*2 + num_bytes);
1274 if (*outbuf == NULL) {
1275 return false;
1278 construct_reply_common(req, inbuf, *outbuf);
1279 srv_set_message(*outbuf, num_words, num_bytes, false);
1281 * Zero out the word area, the caller has to take care of the bcc area
1282 * himself
1284 if (num_words != 0) {
1285 memset(*outbuf + smb_vwv0, 0, num_words*2);
1288 return true;
1291 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1293 char *outbuf;
1294 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1295 num_bytes)) {
1296 smb_panic("could not allocate output buffer\n");
1298 req->outbuf = (uint8_t *)outbuf;
1302 /*******************************************************************
1303 Dump a packet to a file.
1304 ********************************************************************/
1306 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1308 int fd, i;
1309 char *fname = NULL;
1310 if (DEBUGLEVEL < 50) {
1311 return;
1314 if (len < 4) len = smb_len(data)+4;
1315 for (i=1;i<100;i++) {
1316 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1317 type ? "req" : "resp") == -1) {
1318 return;
1320 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1321 if (fd != -1 || errno != EEXIST) break;
1323 if (fd != -1) {
1324 ssize_t ret = write(fd, data, len);
1325 if (ret != len)
1326 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1327 close(fd);
1328 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1330 SAFE_FREE(fname);
1333 /****************************************************************************
1334 Prepare everything for calling the actual request function, and potentially
1335 call the request function via the "new" interface.
1337 Return False if the "legacy" function needs to be called, everything is
1338 prepared.
1340 Return True if we're done.
1342 I know this API sucks, but it is the one with the least code change I could
1343 find.
1344 ****************************************************************************/
1346 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1348 int flags;
1349 uint16 session_tag;
1350 connection_struct *conn = NULL;
1351 struct smbd_server_connection *sconn = req->sconn;
1352 char *raddr;
1354 errno = 0;
1356 if (smb_messages[type].fn == NULL) {
1357 DEBUG(0,("Unknown message type %d!\n",type));
1358 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1359 reply_unknown_new(req, type);
1360 return NULL;
1363 flags = smb_messages[type].flags;
1365 /* In share mode security we must ignore the vuid. */
1366 session_tag = (lp_security() == SEC_SHARE)
1367 ? UID_FIELD_INVALID : req->vuid;
1368 conn = req->conn;
1370 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1371 (int)sys_getpid(), (unsigned long)conn));
1373 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1375 /* Ensure this value is replaced in the incoming packet. */
1376 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1379 * Ensure the correct username is in current_user_info. This is a
1380 * really ugly bugfix for problems with multiple session_setup_and_X's
1381 * being done and allowing %U and %G substitutions to work correctly.
1382 * There is a reason this code is done here, don't move it unless you
1383 * know what you're doing... :-).
1384 * JRA.
1387 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1388 user_struct *vuser = NULL;
1390 sconn->smb1.sessions.last_session_tag = session_tag;
1391 if(session_tag != UID_FIELD_INVALID) {
1392 vuser = get_valid_user_struct(sconn, session_tag);
1393 if (vuser) {
1394 set_current_user_info(
1395 vuser->session_info->unix_info->sanitized_username,
1396 vuser->session_info->unix_info->unix_name,
1397 vuser->session_info->info->domain_name);
1402 /* Does this call need to be run as the connected user? */
1403 if (flags & AS_USER) {
1405 /* Does this call need a valid tree connection? */
1406 if (!conn) {
1408 * Amazingly, the error code depends on the command
1409 * (from Samba4).
1411 if (type == SMBntcreateX) {
1412 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1413 } else {
1414 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1416 return NULL;
1419 if (!change_to_user(conn,session_tag)) {
1420 DEBUG(0, ("Error: Could not change to user. Removing "
1421 "deferred open, mid=%llu.\n",
1422 (unsigned long long)req->mid));
1423 reply_force_doserror(req, ERRSRV, ERRbaduid);
1424 return conn;
1427 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1429 /* Does it need write permission? */
1430 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1431 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1432 return conn;
1435 /* IPC services are limited */
1436 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1437 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1438 return conn;
1440 } else {
1441 /* This call needs to be run as root */
1442 change_to_root_user();
1445 /* load service specific parameters */
1446 if (conn) {
1447 if (req->encrypted) {
1448 conn->encrypted_tid = true;
1449 /* encrypted required from now on. */
1450 conn->encrypt_level = Required;
1451 } else if (ENCRYPTION_REQUIRED(conn)) {
1452 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1453 exit_server_cleanly("encryption required "
1454 "on connection");
1455 return conn;
1459 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1460 (flags & (AS_USER|DO_CHDIR)
1461 ?True:False))) {
1462 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1463 return conn;
1465 conn->num_smb_operations++;
1468 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1469 talloc_tos());
1470 if (raddr == NULL) {
1471 reply_nterror(req, NT_STATUS_NO_MEMORY);
1472 return conn;
1475 /* does this protocol need to be run as guest? */
1476 if ((flags & AS_GUEST)
1477 && (!change_to_guest() ||
1478 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1479 sconn->remote_hostname,
1480 raddr))) {
1481 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1482 return conn;
1485 smb_messages[type].fn(req);
1486 return req->conn;
1489 /****************************************************************************
1490 Construct a reply to the incoming packet.
1491 ****************************************************************************/
1493 static void construct_reply(struct smbd_server_connection *sconn,
1494 char *inbuf, int size, size_t unread_bytes,
1495 uint32_t seqnum, bool encrypted,
1496 struct smb_perfcount_data *deferred_pcd)
1498 connection_struct *conn;
1499 struct smb_request *req;
1501 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1502 smb_panic("could not allocate smb_request");
1505 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1506 encrypted, seqnum)) {
1507 exit_server_cleanly("Invalid SMB request");
1510 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1512 /* we popped this message off the queue - keep original perf data */
1513 if (deferred_pcd)
1514 req->pcd = *deferred_pcd;
1515 else {
1516 SMB_PERFCOUNT_START(&req->pcd);
1517 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1518 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1521 conn = switch_message(req->cmd, req, size);
1523 if (req->unread_bytes) {
1524 /* writeX failed. drain socket. */
1525 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1526 req->unread_bytes) {
1527 smb_panic("failed to drain pending bytes");
1529 req->unread_bytes = 0;
1532 if (req->done) {
1533 TALLOC_FREE(req);
1534 return;
1537 if (req->outbuf == NULL) {
1538 return;
1541 if (CVAL(req->outbuf,0) == 0) {
1542 show_msg((char *)req->outbuf);
1545 if (!srv_send_smb(req->sconn,
1546 (char *)req->outbuf,
1547 true, req->seqnum+1,
1548 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1549 &req->pcd)) {
1550 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1553 TALLOC_FREE(req);
1555 return;
1558 /****************************************************************************
1559 Process an smb from the client
1560 ****************************************************************************/
1561 static void process_smb(struct smbd_server_connection *sconn,
1562 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1563 uint32_t seqnum, bool encrypted,
1564 struct smb_perfcount_data *deferred_pcd)
1566 int msg_type = CVAL(inbuf,0);
1568 DO_PROFILE_INC(smb_count);
1570 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1571 smb_len(inbuf) ) );
1572 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1573 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1575 if (msg_type != NBSSmessage) {
1577 * NetBIOS session request, keepalive, etc.
1579 reply_special(sconn, (char *)inbuf, nread);
1580 goto done;
1583 if (sconn->using_smb2) {
1584 /* At this point we're not really using smb2,
1585 * we make the decision here.. */
1586 if (smbd_is_smb2_header(inbuf, nread)) {
1587 smbd_smb2_first_negprot(sconn, inbuf, nread);
1588 return;
1589 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1590 && CVAL(inbuf, smb_com) != 0x72) {
1591 /* This is a non-negprot SMB1 packet.
1592 Disable SMB2 from now on. */
1593 sconn->using_smb2 = false;
1597 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1598 * so subtract 4 from it. */
1599 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1600 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1601 smb_len(inbuf)));
1603 /* special magic for immediate exit */
1604 if ((nread == 9) &&
1605 (IVAL(inbuf, 4) == 0x74697865) &&
1606 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1607 uint8_t exitcode = CVAL(inbuf, 8);
1608 DEBUG(1, ("Exiting immediately with code %d\n",
1609 (int)exitcode));
1610 exit(exitcode);
1613 exit_server_cleanly("Non-SMB packet");
1616 show_msg((char *)inbuf);
1618 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1619 encrypted, deferred_pcd);
1620 sconn->trans_num++;
1622 done:
1623 sconn->num_requests++;
1625 /* The timeout_processing function isn't run nearly
1626 often enough to implement 'max log size' without
1627 overrunning the size of the file by many megabytes.
1628 This is especially true if we are running at debug
1629 level 10. Checking every 50 SMBs is a nice
1630 tradeoff of performance vs log file size overrun. */
1632 if ((sconn->num_requests % 50) == 0 &&
1633 need_to_check_log_size()) {
1634 change_to_root_user();
1635 check_log_size();
1639 /****************************************************************************
1640 Return a string containing the function name of a SMB command.
1641 ****************************************************************************/
1643 const char *smb_fn_name(int type)
1645 const char *unknown_name = "SMBunknown";
1647 if (smb_messages[type].name == NULL)
1648 return(unknown_name);
1650 return(smb_messages[type].name);
1653 /****************************************************************************
1654 Helper functions for contruct_reply.
1655 ****************************************************************************/
1657 void add_to_common_flags2(uint32 v)
1659 common_flags2 |= v;
1662 void remove_from_common_flags2(uint32 v)
1664 common_flags2 &= ~v;
1667 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1668 char *outbuf)
1670 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1671 uint16_t out_flags2 = common_flags2;
1673 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1674 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1675 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1677 srv_set_message(outbuf,0,0,false);
1679 SCVAL(outbuf, smb_com, req->cmd);
1680 SIVAL(outbuf,smb_rcls,0);
1681 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1682 SSVAL(outbuf,smb_flg2, out_flags2);
1683 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1684 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1686 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1687 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1688 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1689 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1692 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1694 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1698 * How many bytes have we already accumulated up to the current wct field
1699 * offset?
1702 size_t req_wct_ofs(struct smb_request *req)
1704 size_t buf_size;
1706 if (req->chain_outbuf == NULL) {
1707 return smb_wct - 4;
1709 buf_size = talloc_get_size(req->chain_outbuf);
1710 if ((buf_size % 4) != 0) {
1711 buf_size += (4 - (buf_size % 4));
1713 return buf_size - 4;
1717 * Hack around reply_nterror & friends not being aware of chained requests,
1718 * generating illegal (i.e. wct==0) chain replies.
1721 static void fixup_chain_error_packet(struct smb_request *req)
1723 uint8_t *outbuf = req->outbuf;
1724 req->outbuf = NULL;
1725 reply_outbuf(req, 2, 0);
1726 memcpy(req->outbuf, outbuf, smb_wct);
1727 TALLOC_FREE(outbuf);
1728 SCVAL(req->outbuf, smb_vwv0, 0xff);
1732 * @brief Find the smb_cmd offset of the last command pushed
1733 * @param[in] buf The buffer we're building up
1734 * @retval Where can we put our next andx cmd?
1736 * While chaining requests, the "next" request we're looking at needs to put
1737 * its SMB_Command before the data the previous request already built up added
1738 * to the chain. Find the offset to the place where we have to put our cmd.
1741 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1743 uint8_t cmd;
1744 size_t ofs;
1746 cmd = CVAL(buf, smb_com);
1748 SMB_ASSERT(is_andx_req(cmd));
1750 ofs = smb_vwv0;
1752 while (CVAL(buf, ofs) != 0xff) {
1754 if (!is_andx_req(CVAL(buf, ofs))) {
1755 return false;
1759 * ofs is from start of smb header, so add the 4 length
1760 * bytes. The next cmd is right after the wct field.
1762 ofs = SVAL(buf, ofs+2) + 4 + 1;
1764 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1767 *pofs = ofs;
1768 return true;
1772 * @brief Do the smb chaining at a buffer level
1773 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1774 * @param[in] smb_command The command that we want to issue
1775 * @param[in] wct How many words?
1776 * @param[in] vwv The words, already in network order
1777 * @param[in] bytes_alignment How shall we align "bytes"?
1778 * @param[in] num_bytes How many bytes?
1779 * @param[in] bytes The data the request ships
1781 * smb_splice_chain() adds the vwv and bytes to the request already present in
1782 * *poutbuf.
1785 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1786 uint8_t wct, const uint16_t *vwv,
1787 size_t bytes_alignment,
1788 uint32_t num_bytes, const uint8_t *bytes)
1790 uint8_t *outbuf;
1791 size_t old_size, new_size;
1792 size_t ofs;
1793 size_t chain_padding = 0;
1794 size_t bytes_padding = 0;
1795 bool first_request;
1797 old_size = talloc_get_size(*poutbuf);
1800 * old_size == smb_wct means we're pushing the first request in for
1801 * libsmb/
1804 first_request = (old_size == smb_wct);
1806 if (!first_request && ((old_size % 4) != 0)) {
1808 * Align the wct field of subsequent requests to a 4-byte
1809 * boundary
1811 chain_padding = 4 - (old_size % 4);
1815 * After the old request comes the new wct field (1 byte), the vwv's
1816 * and the num_bytes field. After at we might need to align the bytes
1817 * given to us to "bytes_alignment", increasing the num_bytes value.
1820 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1822 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1823 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1826 new_size += bytes_padding + num_bytes;
1828 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1829 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1830 (unsigned)new_size));
1831 return false;
1834 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1835 if (outbuf == NULL) {
1836 DEBUG(0, ("talloc failed\n"));
1837 return false;
1839 *poutbuf = outbuf;
1841 if (first_request) {
1842 SCVAL(outbuf, smb_com, smb_command);
1843 } else {
1844 size_t andx_cmd_ofs;
1846 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1847 DEBUG(1, ("invalid command chain\n"));
1848 *poutbuf = talloc_realloc(
1849 NULL, *poutbuf, uint8_t, old_size);
1850 return false;
1853 if (chain_padding != 0) {
1854 memset(outbuf + old_size, 0, chain_padding);
1855 old_size += chain_padding;
1858 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1859 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1862 ofs = old_size;
1865 * Push the chained request:
1867 * wct field
1870 SCVAL(outbuf, ofs, wct);
1871 ofs += 1;
1874 * vwv array
1877 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1878 ofs += sizeof(uint16_t) * wct;
1881 * bcc (byte count)
1884 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1885 ofs += sizeof(uint16_t);
1888 * padding
1891 if (bytes_padding != 0) {
1892 memset(outbuf + ofs, 0, bytes_padding);
1893 ofs += bytes_padding;
1897 * The bytes field
1900 memcpy(outbuf + ofs, bytes, num_bytes);
1902 return true;
1905 /****************************************************************************
1906 Construct a chained reply and add it to the already made reply
1907 ****************************************************************************/
1909 void chain_reply(struct smb_request *req)
1911 size_t smblen = smb_len(req->inbuf);
1912 size_t already_used, length_needed;
1913 uint8_t chain_cmd;
1914 uint32_t chain_offset; /* uint32_t to avoid overflow */
1916 uint8_t wct;
1917 const uint16_t *vwv;
1918 uint16_t buflen;
1919 const uint8_t *buf;
1921 if (IVAL(req->outbuf, smb_rcls) != 0) {
1922 fixup_chain_error_packet(req);
1926 * Any of the AndX requests and replies have at least a wct of
1927 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1928 * beginning of the SMB header to the next wct field.
1930 * None of the AndX requests put anything valuable in vwv[0] and [1],
1931 * so we can overwrite it here to form the chain.
1934 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1935 if (req->chain_outbuf == NULL) {
1936 req->chain_outbuf = talloc_realloc(
1937 req, req->outbuf, uint8_t,
1938 smb_len(req->outbuf) + 4);
1939 if (req->chain_outbuf == NULL) {
1940 smb_panic("talloc failed");
1943 req->outbuf = NULL;
1944 goto error;
1948 * Here we assume that this is the end of the chain. For that we need
1949 * to set "next command" to 0xff and the offset to 0. If we later find
1950 * more commands in the chain, this will be overwritten again.
1953 SCVAL(req->outbuf, smb_vwv0, 0xff);
1954 SCVAL(req->outbuf, smb_vwv0+1, 0);
1955 SSVAL(req->outbuf, smb_vwv1, 0);
1957 if (req->chain_outbuf == NULL) {
1959 * In req->chain_outbuf we collect all the replies. Start the
1960 * chain by copying in the first reply.
1962 * We do the realloc because later on we depend on
1963 * talloc_get_size to determine the length of
1964 * chain_outbuf. The reply_xxx routines might have
1965 * over-allocated (reply_pipe_read_and_X used to be such an
1966 * example).
1968 req->chain_outbuf = talloc_realloc(
1969 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1970 if (req->chain_outbuf == NULL) {
1971 smb_panic("talloc failed");
1973 req->outbuf = NULL;
1974 } else {
1976 * Update smb headers where subsequent chained commands
1977 * may have updated them.
1979 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1980 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1982 if (!smb_splice_chain(&req->chain_outbuf,
1983 CVAL(req->outbuf, smb_com),
1984 CVAL(req->outbuf, smb_wct),
1985 (uint16_t *)(req->outbuf + smb_vwv),
1986 0, smb_buflen(req->outbuf),
1987 (uint8_t *)smb_buf(req->outbuf))) {
1988 goto error;
1990 TALLOC_FREE(req->outbuf);
1994 * We use the old request's vwv field to grab the next chained command
1995 * and offset into the chained fields.
1998 chain_cmd = CVAL(req->vwv+0, 0);
1999 chain_offset = SVAL(req->vwv+1, 0);
2001 if (chain_cmd == 0xff) {
2003 * End of chain, no more requests from the client. So ship the
2004 * replies.
2006 smb_setlen((char *)(req->chain_outbuf),
2007 talloc_get_size(req->chain_outbuf) - 4);
2009 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2010 true, req->seqnum+1,
2011 IS_CONN_ENCRYPTED(req->conn)
2012 ||req->encrypted,
2013 &req->pcd)) {
2014 exit_server_cleanly("chain_reply: srv_send_smb "
2015 "failed.");
2017 TALLOC_FREE(req->chain_outbuf);
2018 req->done = true;
2019 return;
2022 /* add a new perfcounter for this element of chain */
2023 SMB_PERFCOUNT_ADD(&req->pcd);
2024 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2025 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2028 * Check if the client tries to fool us. The chain offset
2029 * needs to point beyond the current request in the chain, it
2030 * needs to strictly grow. Otherwise we might be tricked into
2031 * an endless loop always processing the same request over and
2032 * over again. We used to assume that vwv and the byte buffer
2033 * array in a chain are always attached, but OS/2 the
2034 * Write&X/Read&X chain puts the Read&X vwv array right behind
2035 * the Write&X vwv chain. The Write&X bcc array is put behind
2036 * the Read&X vwv array. So now we check whether the chain
2037 * offset points strictly behind the previous vwv
2038 * array. req->buf points right after the vwv array of the
2039 * previous request. See
2040 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2041 * information.
2044 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2045 if (chain_offset <= already_used) {
2046 goto error;
2050 * Next check: Make sure the chain offset does not point beyond the
2051 * overall smb request length.
2054 length_needed = chain_offset+1; /* wct */
2055 if (length_needed > smblen) {
2056 goto error;
2060 * Now comes the pointer magic. Goal here is to set up req->vwv and
2061 * req->buf correctly again to be able to call the subsequent
2062 * switch_message(). The chain offset (the former vwv[1]) points at
2063 * the new wct field.
2066 wct = CVAL(smb_base(req->inbuf), chain_offset);
2069 * Next consistency check: Make the new vwv array fits in the overall
2070 * smb request.
2073 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2074 if (length_needed > smblen) {
2075 goto error;
2077 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2080 * Now grab the new byte buffer....
2083 buflen = SVAL(vwv+wct, 0);
2086 * .. and check that it fits.
2089 length_needed += buflen;
2090 if (length_needed > smblen) {
2091 goto error;
2093 buf = (const uint8_t *)(vwv+wct+1);
2095 req->cmd = chain_cmd;
2096 req->wct = wct;
2097 req->vwv = discard_const_p(uint16_t, vwv);
2098 req->buflen = buflen;
2099 req->buf = buf;
2101 switch_message(chain_cmd, req, smblen);
2103 if (req->outbuf == NULL) {
2105 * This happens if the chained command has suspended itself or
2106 * if it has called srv_send_smb() itself.
2108 return;
2112 * We end up here if the chained command was not itself chained or
2113 * suspended, but for example a close() command. We now need to splice
2114 * the chained commands' outbuf into the already built up chain_outbuf
2115 * and ship the result.
2117 goto done;
2119 error:
2121 * We end up here if there's any error in the chain syntax. Report a
2122 * DOS error, just like Windows does.
2124 reply_force_doserror(req, ERRSRV, ERRerror);
2125 fixup_chain_error_packet(req);
2127 done:
2129 * This scary statement intends to set the
2130 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2131 * to the value req->outbuf carries
2133 SSVAL(req->chain_outbuf, smb_flg2,
2134 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2135 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2138 * Transfer the error codes from the subrequest to the main one
2140 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2141 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2143 if (!smb_splice_chain(&req->chain_outbuf,
2144 CVAL(req->outbuf, smb_com),
2145 CVAL(req->outbuf, smb_wct),
2146 (uint16_t *)(req->outbuf + smb_vwv),
2147 0, smb_buflen(req->outbuf),
2148 (uint8_t *)smb_buf(req->outbuf))) {
2149 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2151 TALLOC_FREE(req->outbuf);
2153 smb_setlen((char *)(req->chain_outbuf),
2154 talloc_get_size(req->chain_outbuf) - 4);
2156 show_msg((char *)(req->chain_outbuf));
2158 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2159 true, req->seqnum+1,
2160 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2161 &req->pcd)) {
2162 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2164 TALLOC_FREE(req->chain_outbuf);
2165 req->done = true;
2168 /****************************************************************************
2169 Check if services need reloading.
2170 ****************************************************************************/
2172 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2175 if (last_smb_conf_reload_time == 0) {
2176 last_smb_conf_reload_time = t;
2179 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2180 reload_services(sconn, conn_snum_used, true);
2181 last_smb_conf_reload_time = t;
2185 static bool fd_is_readable(int fd)
2187 int ret, revents;
2189 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2191 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2195 static void smbd_server_connection_write_handler(
2196 struct smbd_server_connection *sconn)
2198 /* TODO: make write nonblocking */
2201 static void smbd_server_connection_read_handler(
2202 struct smbd_server_connection *sconn, int fd)
2204 uint8_t *inbuf = NULL;
2205 size_t inbuf_len = 0;
2206 size_t unread_bytes = 0;
2207 bool encrypted = false;
2208 TALLOC_CTX *mem_ctx = talloc_tos();
2209 NTSTATUS status;
2210 uint32_t seqnum;
2212 bool from_client;
2214 if (lp_async_smb_echo_handler()
2215 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2217 * This is the super-ugly hack to prefer the packets
2218 * forwarded by the echo handler over the ones by the
2219 * client directly
2221 fd = sconn->smb1.echo_handler.trusted_fd;
2224 from_client = (sconn->sock == fd);
2226 if (from_client) {
2227 smbd_lock_socket(sconn);
2229 if (!fd_is_readable(fd)) {
2230 DEBUG(10,("the echo listener was faster\n"));
2231 smbd_unlock_socket(sconn);
2232 return;
2236 /* TODO: make this completely nonblocking */
2237 status = receive_smb_talloc(mem_ctx, sconn, fd,
2238 (char **)(void *)&inbuf,
2239 0, /* timeout */
2240 &unread_bytes,
2241 &encrypted,
2242 &inbuf_len, &seqnum,
2243 false /* trusted channel */);
2245 if (from_client) {
2246 smbd_unlock_socket(sconn);
2249 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2250 goto process;
2252 if (NT_STATUS_IS_ERR(status)) {
2253 exit_server_cleanly("failed to receive smb request");
2255 if (!NT_STATUS_IS_OK(status)) {
2256 return;
2259 process:
2260 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2261 seqnum, encrypted, NULL);
2264 static void smbd_server_connection_handler(struct event_context *ev,
2265 struct fd_event *fde,
2266 uint16_t flags,
2267 void *private_data)
2269 struct smbd_server_connection *conn = talloc_get_type(private_data,
2270 struct smbd_server_connection);
2272 if (flags & EVENT_FD_WRITE) {
2273 smbd_server_connection_write_handler(conn);
2274 return;
2276 if (flags & EVENT_FD_READ) {
2277 smbd_server_connection_read_handler(conn, conn->sock);
2278 return;
2282 static void smbd_server_echo_handler(struct event_context *ev,
2283 struct fd_event *fde,
2284 uint16_t flags,
2285 void *private_data)
2287 struct smbd_server_connection *conn = talloc_get_type(private_data,
2288 struct smbd_server_connection);
2290 if (flags & EVENT_FD_WRITE) {
2291 smbd_server_connection_write_handler(conn);
2292 return;
2294 if (flags & EVENT_FD_READ) {
2295 smbd_server_connection_read_handler(
2296 conn, conn->smb1.echo_handler.trusted_fd);
2297 return;
2301 #ifdef CLUSTER_SUPPORT
2302 /****************************************************************************
2303 received when we should release a specific IP
2304 ****************************************************************************/
2305 static void release_ip(const char *ip, void *priv)
2307 const char *addr = (const char *)priv;
2308 const char *p = addr;
2310 if (strncmp("::ffff:", addr, 7) == 0) {
2311 p = addr + 7;
2314 DEBUG(10, ("Got release IP message for %s, "
2315 "our address is %s\n", ip, p));
2317 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2318 /* we can't afford to do a clean exit - that involves
2319 database writes, which would potentially mean we
2320 are still running after the failover has finished -
2321 we have to get rid of this process ID straight
2322 away */
2323 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2324 ip));
2325 /* note we must exit with non-zero status so the unclean handler gets
2326 called in the parent, so that the brl database is tickled */
2327 _exit(1);
2331 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2332 struct sockaddr_storage *client)
2334 socklen_t length;
2335 length = sizeof(*server);
2336 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2337 return -1;
2339 length = sizeof(*client);
2340 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2341 return -1;
2343 return 0;
2345 #endif
2348 * Send keepalive packets to our client
2350 static bool keepalive_fn(const struct timeval *now, void *private_data)
2352 struct smbd_server_connection *sconn = talloc_get_type_abort(
2353 private_data, struct smbd_server_connection);
2354 bool ret;
2356 if (sconn->using_smb2) {
2357 /* Don't do keepalives on an SMB2 connection. */
2358 return false;
2361 smbd_lock_socket(sconn);
2362 ret = send_keepalive(sconn->sock);
2363 smbd_unlock_socket(sconn);
2365 if (!ret) {
2366 char addr[INET6_ADDRSTRLEN];
2368 * Try and give an error message saying what
2369 * client failed.
2371 DEBUG(0, ("send_keepalive failed for client %s. "
2372 "Error %s - exiting\n",
2373 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2374 strerror(errno)));
2375 return False;
2377 return True;
2381 * Do the recurring check if we're idle
2383 static bool deadtime_fn(const struct timeval *now, void *private_data)
2385 struct smbd_server_connection *sconn =
2386 (struct smbd_server_connection *)private_data;
2388 if ((conn_num_open(sconn) == 0)
2389 || (conn_idle_all(sconn, now->tv_sec))) {
2390 DEBUG( 2, ( "Closing idle connection\n" ) );
2391 messaging_send(sconn->msg_ctx,
2392 messaging_server_id(sconn->msg_ctx),
2393 MSG_SHUTDOWN, &data_blob_null);
2394 return False;
2397 return True;
2401 * Do the recurring log file and smb.conf reload checks.
2404 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2406 struct smbd_server_connection *sconn = talloc_get_type_abort(
2407 private_data, struct smbd_server_connection);
2409 DEBUG(5, ("housekeeping\n"));
2411 change_to_root_user();
2413 /* update printer queue caches if necessary */
2414 update_monitored_printq_cache(sconn->msg_ctx);
2416 /* check if we need to reload services */
2417 check_reload(sconn, time_mono(NULL));
2419 /* Change machine password if neccessary. */
2420 attempt_machine_password_change();
2423 * Force a log file check.
2425 force_check_log_size();
2426 check_log_size();
2427 return true;
2431 * Read an smb packet in the echo handler child, giving the parent
2432 * smbd one second to react once the socket becomes readable.
2435 struct smbd_echo_read_state {
2436 struct tevent_context *ev;
2437 struct smbd_server_connection *sconn;
2439 char *buf;
2440 size_t buflen;
2441 uint32_t seqnum;
2444 static void smbd_echo_read_readable(struct tevent_req *subreq);
2445 static void smbd_echo_read_waited(struct tevent_req *subreq);
2447 static struct tevent_req *smbd_echo_read_send(
2448 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2449 struct smbd_server_connection *sconn)
2451 struct tevent_req *req, *subreq;
2452 struct smbd_echo_read_state *state;
2454 req = tevent_req_create(mem_ctx, &state,
2455 struct smbd_echo_read_state);
2456 if (req == NULL) {
2457 return NULL;
2459 state->ev = ev;
2460 state->sconn = sconn;
2462 subreq = wait_for_read_send(state, ev, sconn->sock);
2463 if (tevent_req_nomem(subreq, req)) {
2464 return tevent_req_post(req, ev);
2466 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2467 return req;
2470 static void smbd_echo_read_readable(struct tevent_req *subreq)
2472 struct tevent_req *req = tevent_req_callback_data(
2473 subreq, struct tevent_req);
2474 struct smbd_echo_read_state *state = tevent_req_data(
2475 req, struct smbd_echo_read_state);
2476 bool ok;
2477 int err;
2479 ok = wait_for_read_recv(subreq, &err);
2480 TALLOC_FREE(subreq);
2481 if (!ok) {
2482 tevent_req_nterror(req, map_nt_error_from_unix(err));
2483 return;
2487 * Give the parent smbd one second to step in
2490 subreq = tevent_wakeup_send(
2491 state, state->ev, timeval_current_ofs(1, 0));
2492 if (tevent_req_nomem(subreq, req)) {
2493 return;
2495 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2498 static void smbd_echo_read_waited(struct tevent_req *subreq)
2500 struct tevent_req *req = tevent_req_callback_data(
2501 subreq, struct tevent_req);
2502 struct smbd_echo_read_state *state = tevent_req_data(
2503 req, struct smbd_echo_read_state);
2504 struct smbd_server_connection *sconn = state->sconn;
2505 bool ok;
2506 NTSTATUS status;
2507 size_t unread = 0;
2508 bool encrypted;
2510 ok = tevent_wakeup_recv(subreq);
2511 TALLOC_FREE(subreq);
2512 if (!ok) {
2513 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2514 return;
2517 ok = smbd_lock_socket_internal(sconn);
2518 if (!ok) {
2519 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2520 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2521 return;
2524 if (!fd_is_readable(sconn->sock)) {
2525 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2526 (int)sys_getpid()));
2528 ok = smbd_unlock_socket_internal(sconn);
2529 if (!ok) {
2530 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2531 DEBUG(1, ("%s: failed to unlock socket\n",
2532 __location__));
2533 return;
2536 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2537 if (tevent_req_nomem(subreq, req)) {
2538 return;
2540 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2541 return;
2544 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2545 0 /* timeout */,
2546 &unread,
2547 &encrypted,
2548 &state->buflen,
2549 &state->seqnum,
2550 false /* trusted_channel*/);
2552 if (tevent_req_nterror(req, status)) {
2553 tevent_req_nterror(req, status);
2554 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2555 (int)sys_getpid(), nt_errstr(status)));
2556 return;
2559 ok = smbd_unlock_socket_internal(sconn);
2560 if (!ok) {
2561 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2562 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2563 return;
2565 tevent_req_done(req);
2568 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2569 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2571 struct smbd_echo_read_state *state = tevent_req_data(
2572 req, struct smbd_echo_read_state);
2573 NTSTATUS status;
2575 if (tevent_req_is_nterror(req, &status)) {
2576 return status;
2578 *pbuf = talloc_move(mem_ctx, &state->buf);
2579 *pbuflen = state->buflen;
2580 *pseqnum = state->seqnum;
2581 return NT_STATUS_OK;
2584 struct smbd_echo_state {
2585 struct tevent_context *ev;
2586 struct iovec *pending;
2587 struct smbd_server_connection *sconn;
2588 int parent_pipe;
2590 struct tevent_fd *parent_fde;
2592 struct tevent_req *write_req;
2595 static void smbd_echo_writer_done(struct tevent_req *req);
2597 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2599 int num_pending;
2601 if (state->write_req != NULL) {
2602 return;
2605 num_pending = talloc_array_length(state->pending);
2606 if (num_pending == 0) {
2607 return;
2610 state->write_req = writev_send(state, state->ev, NULL,
2611 state->parent_pipe, false,
2612 state->pending, num_pending);
2613 if (state->write_req == NULL) {
2614 DEBUG(1, ("writev_send failed\n"));
2615 exit(1);
2618 talloc_steal(state->write_req, state->pending);
2619 state->pending = NULL;
2621 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2622 state);
2625 static void smbd_echo_writer_done(struct tevent_req *req)
2627 struct smbd_echo_state *state = tevent_req_callback_data(
2628 req, struct smbd_echo_state);
2629 ssize_t written;
2630 int err;
2632 written = writev_recv(req, &err);
2633 TALLOC_FREE(req);
2634 state->write_req = NULL;
2635 if (written == -1) {
2636 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2637 exit(1);
2639 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2640 smbd_echo_activate_writer(state);
2643 static bool smbd_echo_reply(struct smbd_echo_state *state,
2644 uint8_t *inbuf, size_t inbuf_len,
2645 uint32_t seqnum)
2647 struct smb_request req;
2648 uint16_t num_replies;
2649 size_t out_len;
2650 char *outbuf;
2651 bool ok;
2653 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2654 DEBUG(10, ("Got netbios keepalive\n"));
2656 * Just swallow it
2658 return true;
2661 if (inbuf_len < smb_size) {
2662 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2663 return false;
2665 if (!valid_smb_header(state->sconn, inbuf)) {
2666 DEBUG(10, ("Got invalid SMB header\n"));
2667 return false;
2670 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2671 seqnum)) {
2672 return false;
2674 req.inbuf = inbuf;
2676 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2677 smb_messages[req.cmd].name
2678 ? smb_messages[req.cmd].name : "unknown"));
2680 if (req.cmd != SMBecho) {
2681 return false;
2683 if (req.wct < 1) {
2684 return false;
2687 num_replies = SVAL(req.vwv+0, 0);
2688 if (num_replies != 1) {
2689 /* Not a Windows "Hey, you're still there?" request */
2690 return false;
2693 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2694 1, req.buflen)) {
2695 DEBUG(10, ("create_outbuf failed\n"));
2696 return false;
2698 req.outbuf = (uint8_t *)outbuf;
2700 SSVAL(req.outbuf, smb_vwv0, num_replies);
2702 if (req.buflen > 0) {
2703 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2706 out_len = smb_len(req.outbuf) + 4;
2708 ok = srv_send_smb(req.sconn,
2709 (char *)outbuf,
2710 true, seqnum+1,
2711 false, &req.pcd);
2712 TALLOC_FREE(outbuf);
2713 if (!ok) {
2714 exit(1);
2717 return true;
2720 static void smbd_echo_exit(struct tevent_context *ev,
2721 struct tevent_fd *fde, uint16_t flags,
2722 void *private_data)
2724 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2725 exit(0);
2728 static void smbd_echo_got_packet(struct tevent_req *req);
2730 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2731 int parent_pipe)
2733 struct smbd_echo_state *state;
2734 struct tevent_req *read_req;
2736 state = talloc_zero(sconn, struct smbd_echo_state);
2737 if (state == NULL) {
2738 DEBUG(1, ("talloc failed\n"));
2739 return;
2741 state->sconn = sconn;
2742 state->parent_pipe = parent_pipe;
2743 state->ev = s3_tevent_context_init(state);
2744 if (state->ev == NULL) {
2745 DEBUG(1, ("tevent_context_init failed\n"));
2746 TALLOC_FREE(state);
2747 return;
2749 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2750 TEVENT_FD_READ, smbd_echo_exit,
2751 state);
2752 if (state->parent_fde == NULL) {
2753 DEBUG(1, ("tevent_add_fd failed\n"));
2754 TALLOC_FREE(state);
2755 return;
2758 read_req = smbd_echo_read_send(state, state->ev, sconn);
2759 if (read_req == NULL) {
2760 DEBUG(1, ("smbd_echo_read_send failed\n"));
2761 TALLOC_FREE(state);
2762 return;
2764 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2766 while (true) {
2767 if (tevent_loop_once(state->ev) == -1) {
2768 DEBUG(1, ("tevent_loop_once failed: %s\n",
2769 strerror(errno)));
2770 break;
2773 TALLOC_FREE(state);
2776 static void smbd_echo_got_packet(struct tevent_req *req)
2778 struct smbd_echo_state *state = tevent_req_callback_data(
2779 req, struct smbd_echo_state);
2780 NTSTATUS status;
2781 char *buf = NULL;
2782 size_t buflen = 0;
2783 uint32_t seqnum = 0;
2784 bool reply;
2786 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2787 TALLOC_FREE(req);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2790 nt_errstr(status)));
2791 exit(1);
2794 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2795 if (!reply) {
2796 size_t num_pending;
2797 struct iovec *tmp;
2798 struct iovec *iov;
2800 num_pending = talloc_array_length(state->pending);
2801 tmp = talloc_realloc(state, state->pending, struct iovec,
2802 num_pending+1);
2803 if (tmp == NULL) {
2804 DEBUG(1, ("talloc_realloc failed\n"));
2805 exit(1);
2807 state->pending = tmp;
2809 if (buflen >= smb_size) {
2811 * place the seqnum in the packet so that the main process
2812 * can reply with signing
2814 SIVAL(buf, smb_ss_field, seqnum);
2815 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2818 iov = &state->pending[num_pending];
2819 iov->iov_base = buf;
2820 iov->iov_len = buflen;
2822 DEBUG(10,("echo_handler[%d]: forward to main\n",
2823 (int)sys_getpid()));
2824 smbd_echo_activate_writer(state);
2827 req = smbd_echo_read_send(state, state->ev, state->sconn);
2828 if (req == NULL) {
2829 DEBUG(1, ("smbd_echo_read_send failed\n"));
2830 exit(1);
2832 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2837 * Handle SMBecho requests in a forked child process
2839 bool fork_echo_handler(struct smbd_server_connection *sconn)
2841 int listener_pipe[2];
2842 int res;
2843 pid_t child;
2845 res = pipe(listener_pipe);
2846 if (res == -1) {
2847 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2848 return false;
2850 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2851 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2852 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2853 goto fail;
2856 child = sys_fork();
2857 if (child == 0) {
2858 NTSTATUS status;
2860 close(listener_pipe[0]);
2861 set_blocking(listener_pipe[1], false);
2863 status = reinit_after_fork(sconn->msg_ctx,
2864 sconn->ev_ctx,
2865 false);
2866 if (!NT_STATUS_IS_OK(status)) {
2867 DEBUG(1, ("reinit_after_fork failed: %s\n",
2868 nt_errstr(status)));
2869 exit(1);
2871 smbd_echo_loop(sconn, listener_pipe[1]);
2872 exit(0);
2874 close(listener_pipe[1]);
2875 listener_pipe[1] = -1;
2876 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2878 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2881 * Without smb signing this is the same as the normal smbd
2882 * listener. This needs to change once signing comes in.
2884 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2885 sconn,
2886 sconn->smb1.echo_handler.trusted_fd,
2887 TEVENT_FD_READ,
2888 smbd_server_echo_handler,
2889 sconn);
2890 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2891 DEBUG(1, ("event_add_fd failed\n"));
2892 goto fail;
2895 return true;
2897 fail:
2898 if (listener_pipe[0] != -1) {
2899 close(listener_pipe[0]);
2901 if (listener_pipe[1] != -1) {
2902 close(listener_pipe[1]);
2904 sconn->smb1.echo_handler.trusted_fd = -1;
2905 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2906 close(sconn->smb1.echo_handler.socket_lock_fd);
2908 sconn->smb1.echo_handler.trusted_fd = -1;
2909 sconn->smb1.echo_handler.socket_lock_fd = -1;
2910 return false;
2913 #if CLUSTER_SUPPORT
2915 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2916 struct sockaddr_storage *srv,
2917 struct sockaddr_storage *clnt)
2919 struct ctdbd_connection *cconn;
2920 char tmp_addr[INET6_ADDRSTRLEN];
2921 char *addr;
2923 cconn = messaging_ctdbd_connection();
2924 if (cconn == NULL) {
2925 return NT_STATUS_NO_MEMORY;
2928 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2929 addr = talloc_strdup(cconn, tmp_addr);
2930 if (addr == NULL) {
2931 return NT_STATUS_NO_MEMORY;
2933 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2936 #endif
2938 static bool uid_in_use(const struct user_struct *user, uid_t uid)
2940 while (user) {
2941 if (user->session_info &&
2942 (user->session_info->unix_token->uid == uid)) {
2943 return true;
2945 user = user->next;
2947 return false;
2950 static bool gid_in_use(const struct user_struct *user, gid_t gid)
2952 while (user) {
2953 if (user->session_info != NULL) {
2954 int i;
2955 struct security_unix_token *utok;
2957 utok = user->session_info->unix_token;
2958 if (utok->gid == gid) {
2959 return true;
2961 for(i=0; i<utok->ngroups; i++) {
2962 if (utok->groups[i] == gid) {
2963 return true;
2967 user = user->next;
2969 return false;
2972 static bool sid_in_use(const struct user_struct *user,
2973 const struct dom_sid *psid)
2975 while (user) {
2976 struct security_token *tok;
2978 if (user->session_info == NULL) {
2979 continue;
2981 tok = user->session_info->security_token;
2982 if (tok == NULL) {
2984 * Not sure session_info->security_token can
2985 * ever be NULL. This check might be not
2986 * necessary.
2988 continue;
2990 if (security_token_has_sid(tok, psid)) {
2991 return true;
2993 user = user->next;
2995 return false;
2998 static bool id_in_use(const struct user_struct *user,
2999 const struct id_cache_ref *id)
3001 switch(id->type) {
3002 case UID:
3003 return uid_in_use(user, id->id.uid);
3004 case GID:
3005 return gid_in_use(user, id->id.gid);
3006 case SID:
3007 return sid_in_use(user, &id->id.sid);
3008 default:
3009 break;
3011 return false;
3014 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3015 void *private_data,
3016 uint32_t msg_type,
3017 struct server_id server_id,
3018 DATA_BLOB* data)
3020 const char *msg = (data && data->data)
3021 ? (const char *)data->data : "<NULL>";
3022 struct user_struct *validated_users;
3023 struct id_cache_ref id;
3024 struct smbd_server_connection *sconn =
3025 talloc_get_type_abort(private_data,
3026 struct smbd_server_connection);
3028 validated_users = sconn->smb1.sessions.validated_users;
3030 if (!id_cache_ref_parse(msg, &id)) {
3031 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3032 return;
3035 if (id_in_use(validated_users, &id)) {
3036 exit_server_cleanly(msg);
3038 id_cache_delete_from_cache(&id);
3041 /****************************************************************************
3042 Process commands from the client
3043 ****************************************************************************/
3045 void smbd_process(struct tevent_context *ev_ctx,
3046 struct smbd_server_connection *sconn)
3048 TALLOC_CTX *frame = talloc_stackframe();
3049 struct sockaddr_storage ss;
3050 struct sockaddr *sa = NULL;
3051 socklen_t sa_socklen;
3052 struct tsocket_address *local_address = NULL;
3053 struct tsocket_address *remote_address = NULL;
3054 const char *locaddr = NULL;
3055 const char *remaddr = NULL;
3056 char *rhost;
3057 int ret;
3059 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
3061 * We're not making the decision here,
3062 * we're just allowing the client
3063 * to decide between SMB1 and SMB2
3064 * with the first negprot
3065 * packet.
3067 sconn->using_smb2 = true;
3070 /* Ensure child is set to blocking mode */
3071 set_blocking(sconn->sock,True);
3073 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3074 set_socket_options(sconn->sock, lp_socket_options());
3076 sa = (struct sockaddr *)(void *)&ss;
3077 sa_socklen = sizeof(ss);
3078 ret = getpeername(sconn->sock, sa, &sa_socklen);
3079 if (ret != 0) {
3080 int level = (errno == ENOTCONN)?2:0;
3081 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3082 exit_server_cleanly("getpeername() failed.\n");
3084 ret = tsocket_address_bsd_from_sockaddr(sconn,
3085 sa, sa_socklen,
3086 &remote_address);
3087 if (ret != 0) {
3088 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3089 __location__, strerror(errno)));
3090 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3093 sa = (struct sockaddr *)(void *)&ss;
3094 sa_socklen = sizeof(ss);
3095 ret = getsockname(sconn->sock, sa, &sa_socklen);
3096 if (ret != 0) {
3097 int level = (errno == ENOTCONN)?2:0;
3098 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3099 exit_server_cleanly("getsockname() failed.\n");
3101 ret = tsocket_address_bsd_from_sockaddr(sconn,
3102 sa, sa_socklen,
3103 &local_address);
3104 if (ret != 0) {
3105 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3106 __location__, strerror(errno)));
3107 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3110 sconn->local_address = local_address;
3111 sconn->remote_address = remote_address;
3113 if (tsocket_address_is_inet(local_address, "ip")) {
3114 locaddr = tsocket_address_inet_addr_string(
3115 sconn->local_address,
3116 talloc_tos());
3117 if (locaddr == NULL) {
3118 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3119 __location__, strerror(errno)));
3120 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3122 } else {
3123 locaddr = "0.0.0.0";
3126 if (tsocket_address_is_inet(remote_address, "ip")) {
3127 remaddr = tsocket_address_inet_addr_string(
3128 sconn->remote_address,
3129 talloc_tos());
3130 if (remaddr == NULL) {
3131 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3132 __location__, strerror(errno)));
3133 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3135 } else {
3136 remaddr = "0.0.0.0";
3139 /* this is needed so that we get decent entries
3140 in smbstatus for port 445 connects */
3141 set_remote_machine_name(remaddr, false);
3142 reload_services(sconn, conn_snum_used, true);
3145 * Before the first packet, check the global hosts allow/ hosts deny
3146 * parameters before doing any parsing of packets passed to us by the
3147 * client. This prevents attacks on our parsing code from hosts not in
3148 * the hosts allow list.
3151 ret = get_remote_hostname(remote_address,
3152 &rhost,
3153 talloc_tos());
3154 if (ret < 0) {
3155 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3156 __location__, strerror(errno)));
3157 exit_server_cleanly("get_remote_hostname failed.\n");
3159 if (strequal(rhost, "UNKNOWN")) {
3160 rhost = talloc_strdup(talloc_tos(), remaddr);
3162 sconn->remote_hostname = talloc_move(sconn, &rhost);
3164 sub_set_socket_ids(remaddr,
3165 sconn->remote_hostname,
3166 locaddr);
3168 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3169 sconn->remote_hostname,
3170 remaddr)) {
3172 * send a negative session response "not listening on calling
3173 * name"
3175 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3176 DEBUG( 1, ("Connection denied from %s to %s\n",
3177 tsocket_address_string(remote_address, talloc_tos()),
3178 tsocket_address_string(local_address, talloc_tos())));
3179 (void)srv_send_smb(sconn,(char *)buf, false,
3180 0, false, NULL);
3181 exit_server_cleanly("connection denied");
3184 DEBUG(10, ("Connection allowed from %s to %s\n",
3185 tsocket_address_string(remote_address, talloc_tos()),
3186 tsocket_address_string(local_address, talloc_tos())));
3188 init_modules();
3190 smb_perfcount_init();
3192 if (!init_account_policy()) {
3193 exit_server("Could not open account policy tdb.\n");
3196 if (*lp_rootdir()) {
3197 if (chroot(lp_rootdir()) != 0) {
3198 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3199 exit_server("Failed to chroot()");
3201 if (chdir("/") == -1) {
3202 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3203 exit_server("Failed to chroot()");
3205 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3208 if (!srv_init_signing(sconn)) {
3209 exit_server("Failed to init smb_signing");
3212 /* Setup oplocks */
3213 if (!init_oplocks(sconn))
3214 exit_server("Failed to init oplocks");
3216 /* register our message handlers */
3217 messaging_register(sconn->msg_ctx, sconn,
3218 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3219 messaging_register(sconn->msg_ctx, sconn,
3220 MSG_SMB_CLOSE_FILE, msg_close_file);
3221 messaging_register(sconn->msg_ctx, sconn,
3222 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3224 id_cache_register_msgs(sconn->msg_ctx);
3225 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3226 messaging_register(sconn->msg_ctx, sconn,
3227 ID_CACHE_KILL, smbd_id_cache_kill);
3229 messaging_deregister(sconn->msg_ctx,
3230 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3231 messaging_register(sconn->msg_ctx, sconn,
3232 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3235 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3236 * MSGs to all child processes
3238 messaging_deregister(sconn->msg_ctx,
3239 MSG_DEBUG, NULL);
3240 messaging_register(sconn->msg_ctx, NULL,
3241 MSG_DEBUG, debug_message);
3243 if ((lp_keepalive() != 0)
3244 && !(event_add_idle(ev_ctx, NULL,
3245 timeval_set(lp_keepalive(), 0),
3246 "keepalive", keepalive_fn,
3247 sconn))) {
3248 DEBUG(0, ("Could not add keepalive event\n"));
3249 exit(1);
3252 if (!(event_add_idle(ev_ctx, NULL,
3253 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3254 "deadtime", deadtime_fn, sconn))) {
3255 DEBUG(0, ("Could not add deadtime event\n"));
3256 exit(1);
3259 if (!(event_add_idle(ev_ctx, NULL,
3260 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3261 "housekeeping", housekeeping_fn, sconn))) {
3262 DEBUG(0, ("Could not add housekeeping event\n"));
3263 exit(1);
3266 #ifdef CLUSTER_SUPPORT
3268 if (lp_clustering()) {
3270 * We need to tell ctdb about our client's TCP
3271 * connection, so that for failover ctdbd can send
3272 * tickle acks, triggering a reconnection by the
3273 * client.
3276 struct sockaddr_storage srv, clnt;
3278 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3279 NTSTATUS status;
3280 status = smbd_register_ips(sconn, &srv, &clnt);
3281 if (!NT_STATUS_IS_OK(status)) {
3282 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3283 nt_errstr(status)));
3285 } else
3287 DEBUG(0,("Unable to get tcp info for "
3288 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3289 strerror(errno)));
3293 #endif
3295 sconn->nbt.got_session = false;
3297 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3299 sconn->smb1.sessions.done_sesssetup = false;
3300 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3301 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3302 /* users from session setup */
3303 sconn->smb1.sessions.session_userlist = NULL;
3304 /* workgroup from session setup. */
3305 sconn->smb1.sessions.session_workgroup = NULL;
3306 /* this holds info on user ids that are already validated for this VC */
3307 sconn->smb1.sessions.validated_users = NULL;
3308 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3309 sconn->smb1.sessions.num_validated_vuids = 0;
3311 conn_init(sconn);
3312 if (!init_dptrs(sconn)) {
3313 exit_server("init_dptrs() failed");
3316 sconn->smb1.fde = event_add_fd(ev_ctx,
3317 sconn,
3318 sconn->sock,
3319 EVENT_FD_READ,
3320 smbd_server_connection_handler,
3321 sconn);
3322 if (!sconn->smb1.fde) {
3323 exit_server("failed to create smbd_server_connection fde");
3326 TALLOC_FREE(frame);
3328 while (True) {
3329 frame = talloc_stackframe_pool(8192);
3331 errno = 0;
3332 if (tevent_loop_once(ev_ctx) == -1) {
3333 if (errno != EINTR) {
3334 DEBUG(3, ("tevent_loop_once failed: %s,"
3335 " exiting\n", strerror(errno) ));
3336 break;
3340 TALLOC_FREE(frame);
3343 exit_server_cleanly(NULL);
3346 bool req_is_in_chain(struct smb_request *req)
3348 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3350 * We're right now handling a subsequent request, so we must
3351 * be in a chain
3353 return true;
3356 if (!is_andx_req(req->cmd)) {
3357 return false;
3360 if (req->wct < 2) {
3362 * Okay, an illegal request, but definitely not chained :-)
3364 return false;
3367 return (CVAL(req->vwv+0, 0) != 0xFF);