s3: Remove a bunch of calls to procid_self()
[Samba/id10ts.git] / source3 / smbd / process.c
blob3b3c1040cec0f8cc1eba6fb1d6a1f0c9afa73319
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"
40 extern bool global_machine_password_needs_changing;
42 /* Internal message queue for deferred opens. */
43 struct pending_message_list {
44 struct pending_message_list *next, *prev;
45 struct timeval request_time; /* When was this first issued? */
46 struct smbd_server_connection *sconn;
47 struct timed_event *te;
48 struct smb_perfcount_data pcd;
49 uint32_t seqnum;
50 bool encrypted;
51 bool processed;
52 DATA_BLOB buf;
53 DATA_BLOB private_data;
56 static void construct_reply_common(struct smb_request *req, const char *inbuf,
57 char *outbuf);
58 static struct pending_message_list *get_deferred_open_message_smb(
59 struct smbd_server_connection *sconn, uint64_t mid);
61 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
63 bool ok;
65 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
66 return true;
69 sconn->smb1.echo_handler.ref_count++;
71 if (sconn->smb1.echo_handler.ref_count > 1) {
72 return true;
75 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
77 do {
78 ok = fcntl_lock(
79 sconn->smb1.echo_handler.socket_lock_fd,
80 SMB_F_SETLKW, 0, 0, F_WRLCK);
81 } while (!ok && (errno == EINTR));
83 if (!ok) {
84 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
85 return false;
88 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
90 return true;
93 void smbd_lock_socket(struct smbd_server_connection *sconn)
95 if (!smbd_lock_socket_internal(sconn)) {
96 exit_server_cleanly("failed to lock socket");
100 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
102 bool ok;
104 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
105 return true;
108 sconn->smb1.echo_handler.ref_count--;
110 if (sconn->smb1.echo_handler.ref_count > 0) {
111 return true;
114 do {
115 ok = fcntl_lock(
116 sconn->smb1.echo_handler.socket_lock_fd,
117 SMB_F_SETLKW, 0, 0, F_UNLCK);
118 } while (!ok && (errno == EINTR));
120 if (!ok) {
121 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
122 return false;
125 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
127 return true;
130 void smbd_unlock_socket(struct smbd_server_connection *sconn)
132 if (!smbd_unlock_socket_internal(sconn)) {
133 exit_server_cleanly("failed to unlock socket");
137 /* Accessor function for smb_read_error for smbd functions. */
139 /****************************************************************************
140 Send an smb to a fd.
141 ****************************************************************************/
143 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
144 bool do_signing, uint32_t seqnum,
145 bool do_encrypt,
146 struct smb_perfcount_data *pcd)
148 size_t len = 0;
149 size_t nwritten=0;
150 ssize_t ret;
151 char *buf_out = buffer;
153 smbd_lock_socket(sconn);
155 if (do_signing) {
156 /* Sign the outgoing packet if required. */
157 srv_calculate_sign_mac(sconn, buf_out, seqnum);
160 if (do_encrypt) {
161 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
162 if (!NT_STATUS_IS_OK(status)) {
163 DEBUG(0, ("send_smb: SMB encryption failed "
164 "on outgoing packet! Error %s\n",
165 nt_errstr(status) ));
166 goto out;
170 len = smb_len(buf_out) + 4;
172 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
173 if (ret <= 0) {
175 char addr[INET6_ADDRSTRLEN];
177 * Try and give an error message saying what
178 * client failed.
180 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
181 (int)sys_getpid(), (int)len,
182 get_peer_addr(sconn->sock, addr, sizeof(addr)),
183 (int)ret, strerror(errno) ));
185 srv_free_enc_buffer(sconn, buf_out);
186 goto out;
189 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
190 srv_free_enc_buffer(sconn, buf_out);
191 out:
192 SMB_PERFCOUNT_END(pcd);
194 smbd_unlock_socket(sconn);
195 return true;
198 /*******************************************************************
199 Setup the word count and byte count for a smb message.
200 ********************************************************************/
202 int srv_set_message(char *buf,
203 int num_words,
204 int num_bytes,
205 bool zero)
207 if (zero && (num_words || num_bytes)) {
208 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
210 SCVAL(buf,smb_wct,num_words);
211 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
212 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
213 return (smb_size + num_words*2 + num_bytes);
216 static bool valid_smb_header(struct smbd_server_connection *sconn,
217 const uint8_t *inbuf)
219 if (is_encrypted_packet(sconn, inbuf)) {
220 return true;
223 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
224 * but it just looks weird to call strncmp for this one.
226 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
229 /* Socket functions for smbd packet processing. */
231 static bool valid_packet_size(size_t len)
234 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
235 * of header. Don't print the error if this fits.... JRA.
238 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
239 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
240 (unsigned long)len));
241 return false;
243 return true;
246 static NTSTATUS read_packet_remainder(int fd, char *buffer,
247 unsigned int timeout, ssize_t len)
249 NTSTATUS status;
251 if (len <= 0) {
252 return NT_STATUS_OK;
255 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
256 if (!NT_STATUS_IS_OK(status)) {
257 char addr[INET6_ADDRSTRLEN];
258 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
259 "error = %s.\n",
260 get_peer_addr(fd, addr, sizeof(addr)),
261 nt_errstr(status)));
263 return status;
266 /****************************************************************************
267 Attempt a zerocopy writeX read. We know here that len > smb_size-4
268 ****************************************************************************/
271 * Unfortunately, earlier versions of smbclient/libsmbclient
272 * don't send this "standard" writeX header. I've fixed this
273 * for 3.2 but we'll use the old method with earlier versions.
274 * Windows and CIFSFS at least use this standard size. Not
275 * sure about MacOSX.
278 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
279 (2*14) + /* word count (including bcc) */ \
280 1 /* pad byte */)
282 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
283 const char lenbuf[4],
284 struct smbd_server_connection *sconn,
285 int sock,
286 char **buffer,
287 unsigned int timeout,
288 size_t *p_unread,
289 size_t *len_ret)
291 /* Size of a WRITEX call (+4 byte len). */
292 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
293 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
294 ssize_t toread;
295 NTSTATUS status;
297 memcpy(writeX_header, lenbuf, 4);
299 status = read_fd_with_timeout(
300 sock, writeX_header + 4,
301 STANDARD_WRITE_AND_X_HEADER_SIZE,
302 STANDARD_WRITE_AND_X_HEADER_SIZE,
303 timeout, NULL);
305 if (!NT_STATUS_IS_OK(status)) {
306 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
307 "error = %s.\n",
308 tsocket_address_string(sconn->remote_address,
309 talloc_tos()),
310 nt_errstr(status)));
311 return status;
315 * Ok - now try and see if this is a possible
316 * valid writeX call.
319 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
321 * If the data offset is beyond what
322 * we've read, drain the extra bytes.
324 uint16_t doff = SVAL(writeX_header,smb_vwv11);
325 ssize_t newlen;
327 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
328 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
329 if (drain_socket(sock, drain) != drain) {
330 smb_panic("receive_smb_raw_talloc_partial_read:"
331 " failed to drain pending bytes");
333 } else {
334 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
337 /* Spoof down the length and null out the bcc. */
338 set_message_bcc(writeX_header, 0);
339 newlen = smb_len(writeX_header);
341 /* Copy the header we've written. */
343 *buffer = (char *)talloc_memdup(mem_ctx,
344 writeX_header,
345 sizeof(writeX_header));
347 if (*buffer == NULL) {
348 DEBUG(0, ("Could not allocate inbuf of length %d\n",
349 (int)sizeof(writeX_header)));
350 return NT_STATUS_NO_MEMORY;
353 /* Work out the remaining bytes. */
354 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
355 *len_ret = newlen + 4;
356 return NT_STATUS_OK;
359 if (!valid_packet_size(len)) {
360 return NT_STATUS_INVALID_PARAMETER;
364 * Not a valid writeX call. Just do the standard
365 * talloc and return.
368 *buffer = talloc_array(mem_ctx, char, len+4);
370 if (*buffer == NULL) {
371 DEBUG(0, ("Could not allocate inbuf of length %d\n",
372 (int)len+4));
373 return NT_STATUS_NO_MEMORY;
376 /* Copy in what we already read. */
377 memcpy(*buffer,
378 writeX_header,
379 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
380 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
382 if(toread > 0) {
383 status = read_packet_remainder(
384 sock,
385 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
386 timeout, toread);
388 if (!NT_STATUS_IS_OK(status)) {
389 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
390 nt_errstr(status)));
391 return status;
395 *len_ret = len + 4;
396 return NT_STATUS_OK;
399 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
400 struct smbd_server_connection *sconn,
401 int sock,
402 char **buffer, unsigned int timeout,
403 size_t *p_unread, size_t *plen)
405 char lenbuf[4];
406 size_t len;
407 int min_recv_size = lp_min_receive_file_size();
408 NTSTATUS status;
410 *p_unread = 0;
412 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
413 &len);
414 if (!NT_STATUS_IS_OK(status)) {
415 return status;
418 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
419 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
420 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
421 !srv_is_signing_active(sconn) &&
422 sconn->smb1.echo_handler.trusted_fde == NULL) {
424 return receive_smb_raw_talloc_partial_read(
425 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
426 p_unread, plen);
429 if (!valid_packet_size(len)) {
430 return NT_STATUS_INVALID_PARAMETER;
434 * The +4 here can't wrap, we've checked the length above already.
437 *buffer = talloc_array(mem_ctx, char, len+4);
439 if (*buffer == NULL) {
440 DEBUG(0, ("Could not allocate inbuf of length %d\n",
441 (int)len+4));
442 return NT_STATUS_NO_MEMORY;
445 memcpy(*buffer, lenbuf, sizeof(lenbuf));
447 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
448 if (!NT_STATUS_IS_OK(status)) {
449 return status;
452 *plen = len + 4;
453 return NT_STATUS_OK;
456 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
457 struct smbd_server_connection *sconn,
458 int sock,
459 char **buffer, unsigned int timeout,
460 size_t *p_unread, bool *p_encrypted,
461 size_t *p_len,
462 uint32_t *seqnum,
463 bool trusted_channel)
465 size_t len = 0;
466 NTSTATUS status;
468 *p_encrypted = false;
470 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
471 p_unread, &len);
472 if (!NT_STATUS_IS_OK(status)) {
473 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
474 ("receive_smb_raw_talloc failed for client %s "
475 "read error = %s.\n",
476 tsocket_address_string(sconn->remote_address,
477 talloc_tos()),
478 nt_errstr(status)) );
479 return status;
482 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
483 status = srv_decrypt_buffer(sconn, *buffer);
484 if (!NT_STATUS_IS_OK(status)) {
485 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
486 "incoming packet! Error %s\n",
487 nt_errstr(status) ));
488 return status;
490 *p_encrypted = true;
493 /* Check the incoming SMB signature. */
494 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
495 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
496 "incoming packet!\n"));
497 return NT_STATUS_INVALID_NETWORK_RESPONSE;
500 *p_len = len;
501 return NT_STATUS_OK;
505 * Initialize a struct smb_request from an inbuf
508 static bool init_smb_request(struct smb_request *req,
509 struct smbd_server_connection *sconn,
510 const uint8 *inbuf,
511 size_t unread_bytes, bool encrypted,
512 uint32_t seqnum)
514 size_t req_size = smb_len(inbuf) + 4;
515 /* Ensure we have at least smb_size bytes. */
516 if (req_size < smb_size) {
517 DEBUG(0,("init_smb_request: invalid request size %u\n",
518 (unsigned int)req_size ));
519 return false;
521 req->cmd = CVAL(inbuf, smb_com);
522 req->flags2 = SVAL(inbuf, smb_flg2);
523 req->smbpid = SVAL(inbuf, smb_pid);
524 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
525 req->seqnum = seqnum;
526 req->vuid = SVAL(inbuf, smb_uid);
527 req->tid = SVAL(inbuf, smb_tid);
528 req->wct = CVAL(inbuf, smb_wct);
529 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
530 req->buflen = smb_buflen(inbuf);
531 req->buf = (const uint8_t *)smb_buf_const(inbuf);
532 req->unread_bytes = unread_bytes;
533 req->encrypted = encrypted;
534 req->sconn = sconn;
535 req->conn = conn_find(sconn,req->tid);
536 req->chain_fsp = NULL;
537 req->chain_outbuf = NULL;
538 req->done = false;
539 req->smb2req = NULL;
540 smb_init_perfcount_data(&req->pcd);
542 /* Ensure we have at least wct words and 2 bytes of bcc. */
543 if (smb_size + req->wct*2 > req_size) {
544 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
545 (unsigned int)req->wct,
546 (unsigned int)req_size));
547 return false;
549 /* Ensure bcc is correct. */
550 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
551 DEBUG(0,("init_smb_request: invalid bcc number %u "
552 "(wct = %u, size %u)\n",
553 (unsigned int)req->buflen,
554 (unsigned int)req->wct,
555 (unsigned int)req_size));
556 return false;
559 req->outbuf = NULL;
560 return true;
563 static void process_smb(struct smbd_server_connection *conn,
564 uint8_t *inbuf, size_t nread, size_t unread_bytes,
565 uint32_t seqnum, bool encrypted,
566 struct smb_perfcount_data *deferred_pcd);
568 static void smbd_deferred_open_timer(struct event_context *ev,
569 struct timed_event *te,
570 struct timeval _tval,
571 void *private_data)
573 struct pending_message_list *msg = talloc_get_type(private_data,
574 struct pending_message_list);
575 struct smbd_server_connection *sconn = msg->sconn;
576 TALLOC_CTX *mem_ctx = talloc_tos();
577 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
578 uint8_t *inbuf;
580 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
581 msg->buf.length);
582 if (inbuf == NULL) {
583 exit_server("smbd_deferred_open_timer: talloc failed\n");
584 return;
587 /* We leave this message on the queue so the open code can
588 know this is a retry. */
589 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
590 (unsigned long long)mid ));
592 /* Mark the message as processed so this is not
593 * re-processed in error. */
594 msg->processed = true;
596 process_smb(sconn, inbuf,
597 msg->buf.length, 0,
598 msg->seqnum, msg->encrypted, &msg->pcd);
600 /* If it's still there and was processed, remove it. */
601 msg = get_deferred_open_message_smb(sconn, mid);
602 if (msg && msg->processed) {
603 remove_deferred_open_message_smb(sconn, mid);
607 /****************************************************************************
608 Function to push a message onto the tail of a linked list of smb messages ready
609 for processing.
610 ****************************************************************************/
612 static bool push_queued_message(struct smb_request *req,
613 struct timeval request_time,
614 struct timeval end_time,
615 char *private_data, size_t private_len)
617 int msg_len = smb_len(req->inbuf) + 4;
618 struct pending_message_list *msg;
620 msg = talloc_zero(NULL, struct pending_message_list);
622 if(msg == NULL) {
623 DEBUG(0,("push_message: malloc fail (1)\n"));
624 return False;
626 msg->sconn = req->sconn;
628 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
629 if(msg->buf.data == NULL) {
630 DEBUG(0,("push_message: malloc fail (2)\n"));
631 TALLOC_FREE(msg);
632 return False;
635 msg->request_time = request_time;
636 msg->seqnum = req->seqnum;
637 msg->encrypted = req->encrypted;
638 msg->processed = false;
639 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
641 if (private_data) {
642 msg->private_data = data_blob_talloc(msg, private_data,
643 private_len);
644 if (msg->private_data.data == NULL) {
645 DEBUG(0,("push_message: malloc fail (3)\n"));
646 TALLOC_FREE(msg);
647 return False;
651 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
652 msg,
653 end_time,
654 smbd_deferred_open_timer,
655 msg);
656 if (!msg->te) {
657 DEBUG(0,("push_message: event_add_timed failed\n"));
658 TALLOC_FREE(msg);
659 return false;
662 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
663 struct pending_message_list *);
665 DEBUG(10,("push_message: pushed message length %u on "
666 "deferred_open_queue\n", (unsigned int)msg_len));
668 return True;
671 /****************************************************************************
672 Function to delete a sharing violation open message by mid.
673 ****************************************************************************/
675 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
676 uint64_t mid)
678 struct pending_message_list *pml;
680 if (sconn->using_smb2) {
681 remove_deferred_open_message_smb2(sconn, mid);
682 return;
685 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
686 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
687 DEBUG(10,("remove_deferred_open_message_smb: "
688 "deleting mid %llu len %u\n",
689 (unsigned long long)mid,
690 (unsigned int)pml->buf.length ));
691 DLIST_REMOVE(sconn->deferred_open_queue, pml);
692 TALLOC_FREE(pml);
693 return;
698 /****************************************************************************
699 Move a sharing violation open retry message to the front of the list and
700 schedule it for immediate processing.
701 ****************************************************************************/
703 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
704 uint64_t mid)
706 struct pending_message_list *pml;
707 int i = 0;
709 if (sconn->using_smb2) {
710 schedule_deferred_open_message_smb2(sconn, mid);
711 return;
714 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
715 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
717 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
718 "msg_mid = %llu\n",
719 i++,
720 (unsigned long long)msg_mid ));
722 if (mid == msg_mid) {
723 struct timed_event *te;
725 if (pml->processed) {
726 /* A processed message should not be
727 * rescheduled. */
728 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
729 "message mid %llu was already processed\n",
730 (unsigned long long)msg_mid ));
731 continue;
734 DEBUG(10,("schedule_deferred_open_message_smb: "
735 "scheduling mid %llu\n",
736 (unsigned long long)mid ));
738 te = tevent_add_timer(pml->sconn->ev_ctx,
739 pml,
740 timeval_zero(),
741 smbd_deferred_open_timer,
742 pml);
743 if (!te) {
744 DEBUG(10,("schedule_deferred_open_message_smb: "
745 "event_add_timed() failed, "
746 "skipping mid %llu\n",
747 (unsigned long long)msg_mid ));
750 TALLOC_FREE(pml->te);
751 pml->te = te;
752 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
753 return;
757 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
758 "find message mid %llu\n",
759 (unsigned long long)mid ));
762 /****************************************************************************
763 Return true if this mid is on the deferred queue and was not yet processed.
764 ****************************************************************************/
766 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
768 struct pending_message_list *pml;
770 if (sconn->using_smb2) {
771 return open_was_deferred_smb2(sconn, mid);
774 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
775 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
776 return True;
779 return False;
782 /****************************************************************************
783 Return the message queued by this mid.
784 ****************************************************************************/
786 static struct pending_message_list *get_deferred_open_message_smb(
787 struct smbd_server_connection *sconn, uint64_t mid)
789 struct pending_message_list *pml;
791 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
792 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
793 return pml;
796 return NULL;
799 /****************************************************************************
800 Get the state data queued by this mid.
801 ****************************************************************************/
803 bool get_deferred_open_message_state(struct smb_request *smbreq,
804 struct timeval *p_request_time,
805 void **pp_state)
807 struct pending_message_list *pml;
809 if (smbreq->sconn->using_smb2) {
810 return get_deferred_open_message_state_smb2(smbreq->smb2req,
811 p_request_time,
812 pp_state);
815 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
816 if (!pml) {
817 return false;
819 if (p_request_time) {
820 *p_request_time = pml->request_time;
822 if (pp_state) {
823 *pp_state = (void *)pml->private_data.data;
825 return true;
828 /****************************************************************************
829 Function to push a deferred open smb message onto a linked list of local smb
830 messages ready for processing.
831 ****************************************************************************/
833 bool push_deferred_open_message_smb(struct smb_request *req,
834 struct timeval request_time,
835 struct timeval timeout,
836 struct file_id id,
837 char *private_data, size_t priv_len)
839 struct timeval end_time;
841 if (req->smb2req) {
842 return push_deferred_open_message_smb2(req->smb2req,
843 request_time,
844 timeout,
846 private_data,
847 priv_len);
850 if (req->unread_bytes) {
851 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
852 "unread_bytes = %u\n",
853 (unsigned int)req->unread_bytes ));
854 smb_panic("push_deferred_open_message_smb: "
855 "logic error unread_bytes != 0" );
858 end_time = timeval_sum(&request_time, &timeout);
860 DEBUG(10,("push_deferred_open_message_smb: pushing message "
861 "len %u mid %llu timeout time [%u.%06u]\n",
862 (unsigned int) smb_len(req->inbuf)+4,
863 (unsigned long long)req->mid,
864 (unsigned int)end_time.tv_sec,
865 (unsigned int)end_time.tv_usec));
867 return push_queued_message(req, request_time, end_time,
868 private_data, priv_len);
871 static void smbd_sig_term_handler(struct tevent_context *ev,
872 struct tevent_signal *se,
873 int signum,
874 int count,
875 void *siginfo,
876 void *private_data)
878 exit_server_cleanly("termination signal");
881 void smbd_setup_sig_term_handler(void)
883 struct tevent_signal *se;
885 se = tevent_add_signal(server_event_context(),
886 server_event_context(),
887 SIGTERM, 0,
888 smbd_sig_term_handler,
889 NULL);
890 if (!se) {
891 exit_server("failed to setup SIGTERM handler");
895 static void smbd_sig_hup_handler(struct tevent_context *ev,
896 struct tevent_signal *se,
897 int signum,
898 int count,
899 void *siginfo,
900 void *private_data)
902 struct messaging_context *msg_ctx = talloc_get_type_abort(
903 private_data, struct messaging_context);
904 change_to_root_user();
905 DEBUG(1,("Reloading services after SIGHUP\n"));
906 reload_services(msg_ctx, smbd_server_conn->sock, False);
907 if (am_parent) {
908 printing_subsystem_update(ev, msg_ctx, true);
912 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
913 struct messaging_context *msg_ctx)
915 struct tevent_signal *se;
917 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
918 msg_ctx);
919 if (!se) {
920 exit_server("failed to setup SIGHUP handler");
924 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
925 struct smbd_server_connection *conn)
927 int timeout;
928 int num_pfds = 0;
929 int ret;
930 bool retry;
932 timeout = SMBD_SELECT_TIMEOUT * 1000;
935 * Are there any timed events waiting ? If so, ensure we don't
936 * select for longer than it would take to wait for them.
939 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
941 /* Process a signal and timed events now... */
942 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
943 return NT_STATUS_RETRY;
947 int sav;
948 START_PROFILE(smbd_idle);
950 ret = sys_poll(conn->pfds, num_pfds, timeout);
951 sav = errno;
953 END_PROFILE(smbd_idle);
954 errno = sav;
957 if (ret == -1) {
958 if (errno == EINTR) {
959 return NT_STATUS_RETRY;
961 return map_nt_error_from_unix(errno);
964 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
965 if (retry) {
966 return NT_STATUS_RETRY;
969 /* Did we timeout ? */
970 if (ret == 0) {
971 return NT_STATUS_RETRY;
974 /* should not be reached */
975 return NT_STATUS_INTERNAL_ERROR;
979 * Only allow 5 outstanding trans requests. We're allocating memory, so
980 * prevent a DoS.
983 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
985 int count = 0;
986 for (; list != NULL; list = list->next) {
988 if (list->mid == mid) {
989 return NT_STATUS_INVALID_PARAMETER;
992 count += 1;
994 if (count > 5) {
995 return NT_STATUS_INSUFFICIENT_RESOURCES;
998 return NT_STATUS_OK;
1002 These flags determine some of the permissions required to do an operation
1004 Note that I don't set NEED_WRITE on some write operations because they
1005 are used by some brain-dead clients when printing, and I don't want to
1006 force write permissions on print services.
1008 #define AS_USER (1<<0)
1009 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1010 #define TIME_INIT (1<<2)
1011 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1012 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1013 #define DO_CHDIR (1<<6)
1016 define a list of possible SMB messages and their corresponding
1017 functions. Any message that has a NULL function is unimplemented -
1018 please feel free to contribute implementations!
1020 static const struct smb_message_struct {
1021 const char *name;
1022 void (*fn)(struct smb_request *req);
1023 int flags;
1024 } smb_messages[256] = {
1026 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1027 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1028 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1029 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1030 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1031 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1032 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1033 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1034 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1035 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1036 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1037 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1038 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1039 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1040 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1041 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1042 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1043 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1044 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1045 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1046 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1047 /* 0x15 */ { NULL, NULL, 0 },
1048 /* 0x16 */ { NULL, NULL, 0 },
1049 /* 0x17 */ { NULL, NULL, 0 },
1050 /* 0x18 */ { NULL, NULL, 0 },
1051 /* 0x19 */ { NULL, NULL, 0 },
1052 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1053 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1054 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1055 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1056 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1057 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1058 /* 0x20 */ { "SMBwritec", NULL,0},
1059 /* 0x21 */ { NULL, NULL, 0 },
1060 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1061 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1062 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1063 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1064 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1065 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1066 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1067 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1068 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1069 /* 0x2b */ { "SMBecho",reply_echo,0},
1070 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1071 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1072 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1073 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1074 /* 0x30 */ { NULL, NULL, 0 },
1075 /* 0x31 */ { NULL, NULL, 0 },
1076 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1077 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1078 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1079 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1080 /* 0x36 */ { NULL, NULL, 0 },
1081 /* 0x37 */ { NULL, NULL, 0 },
1082 /* 0x38 */ { NULL, NULL, 0 },
1083 /* 0x39 */ { NULL, NULL, 0 },
1084 /* 0x3a */ { NULL, NULL, 0 },
1085 /* 0x3b */ { NULL, NULL, 0 },
1086 /* 0x3c */ { NULL, NULL, 0 },
1087 /* 0x3d */ { NULL, NULL, 0 },
1088 /* 0x3e */ { NULL, NULL, 0 },
1089 /* 0x3f */ { NULL, NULL, 0 },
1090 /* 0x40 */ { NULL, NULL, 0 },
1091 /* 0x41 */ { NULL, NULL, 0 },
1092 /* 0x42 */ { NULL, NULL, 0 },
1093 /* 0x43 */ { NULL, NULL, 0 },
1094 /* 0x44 */ { NULL, NULL, 0 },
1095 /* 0x45 */ { NULL, NULL, 0 },
1096 /* 0x46 */ { NULL, NULL, 0 },
1097 /* 0x47 */ { NULL, NULL, 0 },
1098 /* 0x48 */ { NULL, NULL, 0 },
1099 /* 0x49 */ { NULL, NULL, 0 },
1100 /* 0x4a */ { NULL, NULL, 0 },
1101 /* 0x4b */ { NULL, NULL, 0 },
1102 /* 0x4c */ { NULL, NULL, 0 },
1103 /* 0x4d */ { NULL, NULL, 0 },
1104 /* 0x4e */ { NULL, NULL, 0 },
1105 /* 0x4f */ { NULL, NULL, 0 },
1106 /* 0x50 */ { NULL, NULL, 0 },
1107 /* 0x51 */ { NULL, NULL, 0 },
1108 /* 0x52 */ { NULL, NULL, 0 },
1109 /* 0x53 */ { NULL, NULL, 0 },
1110 /* 0x54 */ { NULL, NULL, 0 },
1111 /* 0x55 */ { NULL, NULL, 0 },
1112 /* 0x56 */ { NULL, NULL, 0 },
1113 /* 0x57 */ { NULL, NULL, 0 },
1114 /* 0x58 */ { NULL, NULL, 0 },
1115 /* 0x59 */ { NULL, NULL, 0 },
1116 /* 0x5a */ { NULL, NULL, 0 },
1117 /* 0x5b */ { NULL, NULL, 0 },
1118 /* 0x5c */ { NULL, NULL, 0 },
1119 /* 0x5d */ { NULL, NULL, 0 },
1120 /* 0x5e */ { NULL, NULL, 0 },
1121 /* 0x5f */ { NULL, NULL, 0 },
1122 /* 0x60 */ { NULL, NULL, 0 },
1123 /* 0x61 */ { NULL, NULL, 0 },
1124 /* 0x62 */ { NULL, NULL, 0 },
1125 /* 0x63 */ { NULL, NULL, 0 },
1126 /* 0x64 */ { NULL, NULL, 0 },
1127 /* 0x65 */ { NULL, NULL, 0 },
1128 /* 0x66 */ { NULL, NULL, 0 },
1129 /* 0x67 */ { NULL, NULL, 0 },
1130 /* 0x68 */ { NULL, NULL, 0 },
1131 /* 0x69 */ { NULL, NULL, 0 },
1132 /* 0x6a */ { NULL, NULL, 0 },
1133 /* 0x6b */ { NULL, NULL, 0 },
1134 /* 0x6c */ { NULL, NULL, 0 },
1135 /* 0x6d */ { NULL, NULL, 0 },
1136 /* 0x6e */ { NULL, NULL, 0 },
1137 /* 0x6f */ { NULL, NULL, 0 },
1138 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1139 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1140 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1141 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1142 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1143 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1144 /* 0x76 */ { NULL, NULL, 0 },
1145 /* 0x77 */ { NULL, NULL, 0 },
1146 /* 0x78 */ { NULL, NULL, 0 },
1147 /* 0x79 */ { NULL, NULL, 0 },
1148 /* 0x7a */ { NULL, NULL, 0 },
1149 /* 0x7b */ { NULL, NULL, 0 },
1150 /* 0x7c */ { NULL, NULL, 0 },
1151 /* 0x7d */ { NULL, NULL, 0 },
1152 /* 0x7e */ { NULL, NULL, 0 },
1153 /* 0x7f */ { NULL, NULL, 0 },
1154 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1155 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1156 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1157 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1158 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1159 /* 0x85 */ { NULL, NULL, 0 },
1160 /* 0x86 */ { NULL, NULL, 0 },
1161 /* 0x87 */ { NULL, NULL, 0 },
1162 /* 0x88 */ { NULL, NULL, 0 },
1163 /* 0x89 */ { NULL, NULL, 0 },
1164 /* 0x8a */ { NULL, NULL, 0 },
1165 /* 0x8b */ { NULL, NULL, 0 },
1166 /* 0x8c */ { NULL, NULL, 0 },
1167 /* 0x8d */ { NULL, NULL, 0 },
1168 /* 0x8e */ { NULL, NULL, 0 },
1169 /* 0x8f */ { NULL, NULL, 0 },
1170 /* 0x90 */ { NULL, NULL, 0 },
1171 /* 0x91 */ { NULL, NULL, 0 },
1172 /* 0x92 */ { NULL, NULL, 0 },
1173 /* 0x93 */ { NULL, NULL, 0 },
1174 /* 0x94 */ { NULL, NULL, 0 },
1175 /* 0x95 */ { NULL, NULL, 0 },
1176 /* 0x96 */ { NULL, NULL, 0 },
1177 /* 0x97 */ { NULL, NULL, 0 },
1178 /* 0x98 */ { NULL, NULL, 0 },
1179 /* 0x99 */ { NULL, NULL, 0 },
1180 /* 0x9a */ { NULL, NULL, 0 },
1181 /* 0x9b */ { NULL, NULL, 0 },
1182 /* 0x9c */ { NULL, NULL, 0 },
1183 /* 0x9d */ { NULL, NULL, 0 },
1184 /* 0x9e */ { NULL, NULL, 0 },
1185 /* 0x9f */ { NULL, NULL, 0 },
1186 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1187 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1188 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1189 /* 0xa3 */ { NULL, NULL, 0 },
1190 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1191 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1192 /* 0xa6 */ { NULL, NULL, 0 },
1193 /* 0xa7 */ { NULL, NULL, 0 },
1194 /* 0xa8 */ { NULL, NULL, 0 },
1195 /* 0xa9 */ { NULL, NULL, 0 },
1196 /* 0xaa */ { NULL, NULL, 0 },
1197 /* 0xab */ { NULL, NULL, 0 },
1198 /* 0xac */ { NULL, NULL, 0 },
1199 /* 0xad */ { NULL, NULL, 0 },
1200 /* 0xae */ { NULL, NULL, 0 },
1201 /* 0xaf */ { NULL, NULL, 0 },
1202 /* 0xb0 */ { NULL, NULL, 0 },
1203 /* 0xb1 */ { NULL, NULL, 0 },
1204 /* 0xb2 */ { NULL, NULL, 0 },
1205 /* 0xb3 */ { NULL, NULL, 0 },
1206 /* 0xb4 */ { NULL, NULL, 0 },
1207 /* 0xb5 */ { NULL, NULL, 0 },
1208 /* 0xb6 */ { NULL, NULL, 0 },
1209 /* 0xb7 */ { NULL, NULL, 0 },
1210 /* 0xb8 */ { NULL, NULL, 0 },
1211 /* 0xb9 */ { NULL, NULL, 0 },
1212 /* 0xba */ { NULL, NULL, 0 },
1213 /* 0xbb */ { NULL, NULL, 0 },
1214 /* 0xbc */ { NULL, NULL, 0 },
1215 /* 0xbd */ { NULL, NULL, 0 },
1216 /* 0xbe */ { NULL, NULL, 0 },
1217 /* 0xbf */ { NULL, NULL, 0 },
1218 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1219 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1220 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1221 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1222 /* 0xc4 */ { NULL, NULL, 0 },
1223 /* 0xc5 */ { NULL, NULL, 0 },
1224 /* 0xc6 */ { NULL, NULL, 0 },
1225 /* 0xc7 */ { NULL, NULL, 0 },
1226 /* 0xc8 */ { NULL, NULL, 0 },
1227 /* 0xc9 */ { NULL, NULL, 0 },
1228 /* 0xca */ { NULL, NULL, 0 },
1229 /* 0xcb */ { NULL, NULL, 0 },
1230 /* 0xcc */ { NULL, NULL, 0 },
1231 /* 0xcd */ { NULL, NULL, 0 },
1232 /* 0xce */ { NULL, NULL, 0 },
1233 /* 0xcf */ { NULL, NULL, 0 },
1234 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1235 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1236 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1237 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1238 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1239 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1240 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1241 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1242 /* 0xd8 */ { NULL, NULL, 0 },
1243 /* 0xd9 */ { NULL, NULL, 0 },
1244 /* 0xda */ { NULL, NULL, 0 },
1245 /* 0xdb */ { NULL, NULL, 0 },
1246 /* 0xdc */ { NULL, NULL, 0 },
1247 /* 0xdd */ { NULL, NULL, 0 },
1248 /* 0xde */ { NULL, NULL, 0 },
1249 /* 0xdf */ { NULL, NULL, 0 },
1250 /* 0xe0 */ { NULL, NULL, 0 },
1251 /* 0xe1 */ { NULL, NULL, 0 },
1252 /* 0xe2 */ { NULL, NULL, 0 },
1253 /* 0xe3 */ { NULL, NULL, 0 },
1254 /* 0xe4 */ { NULL, NULL, 0 },
1255 /* 0xe5 */ { NULL, NULL, 0 },
1256 /* 0xe6 */ { NULL, NULL, 0 },
1257 /* 0xe7 */ { NULL, NULL, 0 },
1258 /* 0xe8 */ { NULL, NULL, 0 },
1259 /* 0xe9 */ { NULL, NULL, 0 },
1260 /* 0xea */ { NULL, NULL, 0 },
1261 /* 0xeb */ { NULL, NULL, 0 },
1262 /* 0xec */ { NULL, NULL, 0 },
1263 /* 0xed */ { NULL, NULL, 0 },
1264 /* 0xee */ { NULL, NULL, 0 },
1265 /* 0xef */ { NULL, NULL, 0 },
1266 /* 0xf0 */ { NULL, NULL, 0 },
1267 /* 0xf1 */ { NULL, NULL, 0 },
1268 /* 0xf2 */ { NULL, NULL, 0 },
1269 /* 0xf3 */ { NULL, NULL, 0 },
1270 /* 0xf4 */ { NULL, NULL, 0 },
1271 /* 0xf5 */ { NULL, NULL, 0 },
1272 /* 0xf6 */ { NULL, NULL, 0 },
1273 /* 0xf7 */ { NULL, NULL, 0 },
1274 /* 0xf8 */ { NULL, NULL, 0 },
1275 /* 0xf9 */ { NULL, NULL, 0 },
1276 /* 0xfa */ { NULL, NULL, 0 },
1277 /* 0xfb */ { NULL, NULL, 0 },
1278 /* 0xfc */ { NULL, NULL, 0 },
1279 /* 0xfd */ { NULL, NULL, 0 },
1280 /* 0xfe */ { NULL, NULL, 0 },
1281 /* 0xff */ { NULL, NULL, 0 }
1285 /*******************************************************************
1286 allocate and initialize a reply packet
1287 ********************************************************************/
1289 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1290 const char *inbuf, char **outbuf, uint8_t num_words,
1291 uint32_t num_bytes)
1294 * Protect against integer wrap
1296 if ((num_bytes > 0xffffff)
1297 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1298 char *msg;
1299 if (asprintf(&msg, "num_bytes too large: %u",
1300 (unsigned)num_bytes) == -1) {
1301 msg = discard_const_p(char, "num_bytes too large");
1303 smb_panic(msg);
1306 *outbuf = talloc_array(mem_ctx, char,
1307 smb_size + num_words*2 + num_bytes);
1308 if (*outbuf == NULL) {
1309 return false;
1312 construct_reply_common(req, inbuf, *outbuf);
1313 srv_set_message(*outbuf, num_words, num_bytes, false);
1315 * Zero out the word area, the caller has to take care of the bcc area
1316 * himself
1318 if (num_words != 0) {
1319 memset(*outbuf + smb_vwv0, 0, num_words*2);
1322 return true;
1325 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1327 char *outbuf;
1328 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1329 num_bytes)) {
1330 smb_panic("could not allocate output buffer\n");
1332 req->outbuf = (uint8_t *)outbuf;
1336 /*******************************************************************
1337 Dump a packet to a file.
1338 ********************************************************************/
1340 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1342 int fd, i;
1343 char *fname = NULL;
1344 if (DEBUGLEVEL < 50) {
1345 return;
1348 if (len < 4) len = smb_len(data)+4;
1349 for (i=1;i<100;i++) {
1350 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1351 type ? "req" : "resp") == -1) {
1352 return;
1354 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1355 if (fd != -1 || errno != EEXIST) break;
1357 if (fd != -1) {
1358 ssize_t ret = write(fd, data, len);
1359 if (ret != len)
1360 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1361 close(fd);
1362 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1364 SAFE_FREE(fname);
1367 /****************************************************************************
1368 Prepare everything for calling the actual request function, and potentially
1369 call the request function via the "new" interface.
1371 Return False if the "legacy" function needs to be called, everything is
1372 prepared.
1374 Return True if we're done.
1376 I know this API sucks, but it is the one with the least code change I could
1377 find.
1378 ****************************************************************************/
1380 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1382 int flags;
1383 uint16 session_tag;
1384 connection_struct *conn = NULL;
1385 struct smbd_server_connection *sconn = req->sconn;
1386 char *raddr;
1388 errno = 0;
1390 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1391 * so subtract 4 from it. */
1392 if (!valid_smb_header(sconn, req->inbuf)
1393 || (size < (smb_size - 4))) {
1394 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1395 smb_len(req->inbuf)));
1396 exit_server_cleanly("Non-SMB packet");
1399 if (smb_messages[type].fn == NULL) {
1400 DEBUG(0,("Unknown message type %d!\n",type));
1401 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1402 reply_unknown_new(req, type);
1403 return NULL;
1406 flags = smb_messages[type].flags;
1408 /* In share mode security we must ignore the vuid. */
1409 session_tag = (lp_security() == SEC_SHARE)
1410 ? UID_FIELD_INVALID : req->vuid;
1411 conn = req->conn;
1413 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1414 (int)sys_getpid(), (unsigned long)conn));
1416 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1418 /* Ensure this value is replaced in the incoming packet. */
1419 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1422 * Ensure the correct username is in current_user_info. This is a
1423 * really ugly bugfix for problems with multiple session_setup_and_X's
1424 * being done and allowing %U and %G substitutions to work correctly.
1425 * There is a reason this code is done here, don't move it unless you
1426 * know what you're doing... :-).
1427 * JRA.
1430 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1431 user_struct *vuser = NULL;
1433 sconn->smb1.sessions.last_session_tag = session_tag;
1434 if(session_tag != UID_FIELD_INVALID) {
1435 vuser = get_valid_user_struct(sconn, session_tag);
1436 if (vuser) {
1437 set_current_user_info(
1438 vuser->session_info->unix_info->sanitized_username,
1439 vuser->session_info->unix_info->unix_name,
1440 vuser->session_info->info->domain_name);
1445 /* Does this call need to be run as the connected user? */
1446 if (flags & AS_USER) {
1448 /* Does this call need a valid tree connection? */
1449 if (!conn) {
1451 * Amazingly, the error code depends on the command
1452 * (from Samba4).
1454 if (type == SMBntcreateX) {
1455 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1456 } else {
1457 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1459 return NULL;
1462 if (!change_to_user(conn,session_tag)) {
1463 DEBUG(0, ("Error: Could not change to user. Removing "
1464 "deferred open, mid=%llu.\n",
1465 (unsigned long long)req->mid));
1466 reply_force_doserror(req, ERRSRV, ERRbaduid);
1467 return conn;
1470 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1472 /* Does it need write permission? */
1473 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1474 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1475 return conn;
1478 /* IPC services are limited */
1479 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1480 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1481 return conn;
1483 } else {
1484 /* This call needs to be run as root */
1485 change_to_root_user();
1488 /* load service specific parameters */
1489 if (conn) {
1490 if (req->encrypted) {
1491 conn->encrypted_tid = true;
1492 /* encrypted required from now on. */
1493 conn->encrypt_level = Required;
1494 } else if (ENCRYPTION_REQUIRED(conn)) {
1495 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1496 exit_server_cleanly("encryption required "
1497 "on connection");
1498 return conn;
1502 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1503 (flags & (AS_USER|DO_CHDIR)
1504 ?True:False))) {
1505 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1506 return conn;
1508 conn->num_smb_operations++;
1511 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1512 talloc_tos());
1513 if (raddr == NULL) {
1514 reply_nterror(req, NT_STATUS_NO_MEMORY);
1515 return conn;
1518 /* does this protocol need to be run as guest? */
1519 if ((flags & AS_GUEST)
1520 && (!change_to_guest() ||
1521 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1522 sconn->remote_hostname,
1523 raddr))) {
1524 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1525 return conn;
1528 smb_messages[type].fn(req);
1529 return req->conn;
1532 /****************************************************************************
1533 Construct a reply to the incoming packet.
1534 ****************************************************************************/
1536 static void construct_reply(struct smbd_server_connection *sconn,
1537 char *inbuf, int size, size_t unread_bytes,
1538 uint32_t seqnum, bool encrypted,
1539 struct smb_perfcount_data *deferred_pcd)
1541 connection_struct *conn;
1542 struct smb_request *req;
1544 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1545 smb_panic("could not allocate smb_request");
1548 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1549 encrypted, seqnum)) {
1550 exit_server_cleanly("Invalid SMB request");
1553 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1555 /* we popped this message off the queue - keep original perf data */
1556 if (deferred_pcd)
1557 req->pcd = *deferred_pcd;
1558 else {
1559 SMB_PERFCOUNT_START(&req->pcd);
1560 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1561 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1564 conn = switch_message(req->cmd, req, size);
1566 if (req->unread_bytes) {
1567 /* writeX failed. drain socket. */
1568 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1569 req->unread_bytes) {
1570 smb_panic("failed to drain pending bytes");
1572 req->unread_bytes = 0;
1575 if (req->done) {
1576 TALLOC_FREE(req);
1577 return;
1580 if (req->outbuf == NULL) {
1581 return;
1584 if (CVAL(req->outbuf,0) == 0) {
1585 show_msg((char *)req->outbuf);
1588 if (!srv_send_smb(req->sconn,
1589 (char *)req->outbuf,
1590 true, req->seqnum+1,
1591 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1592 &req->pcd)) {
1593 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1596 TALLOC_FREE(req);
1598 return;
1601 /****************************************************************************
1602 Process an smb from the client
1603 ****************************************************************************/
1604 static void process_smb(struct smbd_server_connection *sconn,
1605 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1606 uint32_t seqnum, bool encrypted,
1607 struct smb_perfcount_data *deferred_pcd)
1609 int msg_type = CVAL(inbuf,0);
1611 DO_PROFILE_INC(smb_count);
1613 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1614 smb_len(inbuf) ) );
1615 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1616 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1618 if (msg_type != NBSSmessage) {
1620 * NetBIOS session request, keepalive, etc.
1622 reply_special(sconn, (char *)inbuf, nread);
1623 goto done;
1626 if (sconn->using_smb2) {
1627 /* At this point we're not really using smb2,
1628 * we make the decision here.. */
1629 if (smbd_is_smb2_header(inbuf, nread)) {
1630 smbd_smb2_first_negprot(sconn, inbuf, nread);
1631 return;
1632 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1633 && CVAL(inbuf, smb_com) != 0x72) {
1634 /* This is a non-negprot SMB1 packet.
1635 Disable SMB2 from now on. */
1636 sconn->using_smb2 = false;
1640 show_msg((char *)inbuf);
1642 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1643 encrypted, deferred_pcd);
1644 sconn->trans_num++;
1646 done:
1647 sconn->num_requests++;
1649 /* The timeout_processing function isn't run nearly
1650 often enough to implement 'max log size' without
1651 overrunning the size of the file by many megabytes.
1652 This is especially true if we are running at debug
1653 level 10. Checking every 50 SMBs is a nice
1654 tradeoff of performance vs log file size overrun. */
1656 if ((sconn->num_requests % 50) == 0 &&
1657 need_to_check_log_size()) {
1658 change_to_root_user();
1659 check_log_size();
1663 /****************************************************************************
1664 Return a string containing the function name of a SMB command.
1665 ****************************************************************************/
1667 const char *smb_fn_name(int type)
1669 const char *unknown_name = "SMBunknown";
1671 if (smb_messages[type].name == NULL)
1672 return(unknown_name);
1674 return(smb_messages[type].name);
1677 /****************************************************************************
1678 Helper functions for contruct_reply.
1679 ****************************************************************************/
1681 void add_to_common_flags2(uint32 v)
1683 common_flags2 |= v;
1686 void remove_from_common_flags2(uint32 v)
1688 common_flags2 &= ~v;
1691 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1692 char *outbuf)
1694 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1695 uint16_t out_flags2 = common_flags2;
1697 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1698 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1699 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1701 srv_set_message(outbuf,0,0,false);
1703 SCVAL(outbuf, smb_com, req->cmd);
1704 SIVAL(outbuf,smb_rcls,0);
1705 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1706 SSVAL(outbuf,smb_flg2, out_flags2);
1707 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1708 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1710 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1711 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1712 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1713 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1716 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1718 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1722 * How many bytes have we already accumulated up to the current wct field
1723 * offset?
1726 size_t req_wct_ofs(struct smb_request *req)
1728 size_t buf_size;
1730 if (req->chain_outbuf == NULL) {
1731 return smb_wct - 4;
1733 buf_size = talloc_get_size(req->chain_outbuf);
1734 if ((buf_size % 4) != 0) {
1735 buf_size += (4 - (buf_size % 4));
1737 return buf_size - 4;
1741 * Hack around reply_nterror & friends not being aware of chained requests,
1742 * generating illegal (i.e. wct==0) chain replies.
1745 static void fixup_chain_error_packet(struct smb_request *req)
1747 uint8_t *outbuf = req->outbuf;
1748 req->outbuf = NULL;
1749 reply_outbuf(req, 2, 0);
1750 memcpy(req->outbuf, outbuf, smb_wct);
1751 TALLOC_FREE(outbuf);
1752 SCVAL(req->outbuf, smb_vwv0, 0xff);
1756 * @brief Find the smb_cmd offset of the last command pushed
1757 * @param[in] buf The buffer we're building up
1758 * @retval Where can we put our next andx cmd?
1760 * While chaining requests, the "next" request we're looking at needs to put
1761 * its SMB_Command before the data the previous request already built up added
1762 * to the chain. Find the offset to the place where we have to put our cmd.
1765 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1767 uint8_t cmd;
1768 size_t ofs;
1770 cmd = CVAL(buf, smb_com);
1772 SMB_ASSERT(is_andx_req(cmd));
1774 ofs = smb_vwv0;
1776 while (CVAL(buf, ofs) != 0xff) {
1778 if (!is_andx_req(CVAL(buf, ofs))) {
1779 return false;
1783 * ofs is from start of smb header, so add the 4 length
1784 * bytes. The next cmd is right after the wct field.
1786 ofs = SVAL(buf, ofs+2) + 4 + 1;
1788 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1791 *pofs = ofs;
1792 return true;
1796 * @brief Do the smb chaining at a buffer level
1797 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1798 * @param[in] smb_command The command that we want to issue
1799 * @param[in] wct How many words?
1800 * @param[in] vwv The words, already in network order
1801 * @param[in] bytes_alignment How shall we align "bytes"?
1802 * @param[in] num_bytes How many bytes?
1803 * @param[in] bytes The data the request ships
1805 * smb_splice_chain() adds the vwv and bytes to the request already present in
1806 * *poutbuf.
1809 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1810 uint8_t wct, const uint16_t *vwv,
1811 size_t bytes_alignment,
1812 uint32_t num_bytes, const uint8_t *bytes)
1814 uint8_t *outbuf;
1815 size_t old_size, new_size;
1816 size_t ofs;
1817 size_t chain_padding = 0;
1818 size_t bytes_padding = 0;
1819 bool first_request;
1821 old_size = talloc_get_size(*poutbuf);
1824 * old_size == smb_wct means we're pushing the first request in for
1825 * libsmb/
1828 first_request = (old_size == smb_wct);
1830 if (!first_request && ((old_size % 4) != 0)) {
1832 * Align the wct field of subsequent requests to a 4-byte
1833 * boundary
1835 chain_padding = 4 - (old_size % 4);
1839 * After the old request comes the new wct field (1 byte), the vwv's
1840 * and the num_bytes field. After at we might need to align the bytes
1841 * given to us to "bytes_alignment", increasing the num_bytes value.
1844 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1846 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1847 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1850 new_size += bytes_padding + num_bytes;
1852 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1853 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1854 (unsigned)new_size));
1855 return false;
1858 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1859 if (outbuf == NULL) {
1860 DEBUG(0, ("talloc failed\n"));
1861 return false;
1863 *poutbuf = outbuf;
1865 if (first_request) {
1866 SCVAL(outbuf, smb_com, smb_command);
1867 } else {
1868 size_t andx_cmd_ofs;
1870 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1871 DEBUG(1, ("invalid command chain\n"));
1872 *poutbuf = talloc_realloc(
1873 NULL, *poutbuf, uint8_t, old_size);
1874 return false;
1877 if (chain_padding != 0) {
1878 memset(outbuf + old_size, 0, chain_padding);
1879 old_size += chain_padding;
1882 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1883 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1886 ofs = old_size;
1889 * Push the chained request:
1891 * wct field
1894 SCVAL(outbuf, ofs, wct);
1895 ofs += 1;
1898 * vwv array
1901 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1902 ofs += sizeof(uint16_t) * wct;
1905 * bcc (byte count)
1908 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1909 ofs += sizeof(uint16_t);
1912 * padding
1915 if (bytes_padding != 0) {
1916 memset(outbuf + ofs, 0, bytes_padding);
1917 ofs += bytes_padding;
1921 * The bytes field
1924 memcpy(outbuf + ofs, bytes, num_bytes);
1926 return true;
1929 /****************************************************************************
1930 Construct a chained reply and add it to the already made reply
1931 ****************************************************************************/
1933 void chain_reply(struct smb_request *req)
1935 size_t smblen = smb_len(req->inbuf);
1936 size_t already_used, length_needed;
1937 uint8_t chain_cmd;
1938 uint32_t chain_offset; /* uint32_t to avoid overflow */
1940 uint8_t wct;
1941 const uint16_t *vwv;
1942 uint16_t buflen;
1943 const uint8_t *buf;
1945 if (IVAL(req->outbuf, smb_rcls) != 0) {
1946 fixup_chain_error_packet(req);
1950 * Any of the AndX requests and replies have at least a wct of
1951 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1952 * beginning of the SMB header to the next wct field.
1954 * None of the AndX requests put anything valuable in vwv[0] and [1],
1955 * so we can overwrite it here to form the chain.
1958 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1959 if (req->chain_outbuf == NULL) {
1960 req->chain_outbuf = talloc_realloc(
1961 req, req->outbuf, uint8_t,
1962 smb_len(req->outbuf) + 4);
1963 if (req->chain_outbuf == NULL) {
1964 smb_panic("talloc failed");
1967 req->outbuf = NULL;
1968 goto error;
1972 * Here we assume that this is the end of the chain. For that we need
1973 * to set "next command" to 0xff and the offset to 0. If we later find
1974 * more commands in the chain, this will be overwritten again.
1977 SCVAL(req->outbuf, smb_vwv0, 0xff);
1978 SCVAL(req->outbuf, smb_vwv0+1, 0);
1979 SSVAL(req->outbuf, smb_vwv1, 0);
1981 if (req->chain_outbuf == NULL) {
1983 * In req->chain_outbuf we collect all the replies. Start the
1984 * chain by copying in the first reply.
1986 * We do the realloc because later on we depend on
1987 * talloc_get_size to determine the length of
1988 * chain_outbuf. The reply_xxx routines might have
1989 * over-allocated (reply_pipe_read_and_X used to be such an
1990 * example).
1992 req->chain_outbuf = talloc_realloc(
1993 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1994 if (req->chain_outbuf == NULL) {
1995 smb_panic("talloc failed");
1997 req->outbuf = NULL;
1998 } else {
2000 * Update smb headers where subsequent chained commands
2001 * may have updated them.
2003 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2004 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2006 if (!smb_splice_chain(&req->chain_outbuf,
2007 CVAL(req->outbuf, smb_com),
2008 CVAL(req->outbuf, smb_wct),
2009 (uint16_t *)(req->outbuf + smb_vwv),
2010 0, smb_buflen(req->outbuf),
2011 (uint8_t *)smb_buf(req->outbuf))) {
2012 goto error;
2014 TALLOC_FREE(req->outbuf);
2018 * We use the old request's vwv field to grab the next chained command
2019 * and offset into the chained fields.
2022 chain_cmd = CVAL(req->vwv+0, 0);
2023 chain_offset = SVAL(req->vwv+1, 0);
2025 if (chain_cmd == 0xff) {
2027 * End of chain, no more requests from the client. So ship the
2028 * replies.
2030 smb_setlen((char *)(req->chain_outbuf),
2031 talloc_get_size(req->chain_outbuf) - 4);
2033 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2034 true, req->seqnum+1,
2035 IS_CONN_ENCRYPTED(req->conn)
2036 ||req->encrypted,
2037 &req->pcd)) {
2038 exit_server_cleanly("chain_reply: srv_send_smb "
2039 "failed.");
2041 TALLOC_FREE(req->chain_outbuf);
2042 req->done = true;
2043 return;
2046 /* add a new perfcounter for this element of chain */
2047 SMB_PERFCOUNT_ADD(&req->pcd);
2048 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2049 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2052 * Check if the client tries to fool us. The chain offset
2053 * needs to point beyond the current request in the chain, it
2054 * needs to strictly grow. Otherwise we might be tricked into
2055 * an endless loop always processing the same request over and
2056 * over again. We used to assume that vwv and the byte buffer
2057 * array in a chain are always attached, but OS/2 the
2058 * Write&X/Read&X chain puts the Read&X vwv array right behind
2059 * the Write&X vwv chain. The Write&X bcc array is put behind
2060 * the Read&X vwv array. So now we check whether the chain
2061 * offset points strictly behind the previous vwv
2062 * array. req->buf points right after the vwv array of the
2063 * previous request. See
2064 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2065 * information.
2068 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2069 if (chain_offset <= already_used) {
2070 goto error;
2074 * Next check: Make sure the chain offset does not point beyond the
2075 * overall smb request length.
2078 length_needed = chain_offset+1; /* wct */
2079 if (length_needed > smblen) {
2080 goto error;
2084 * Now comes the pointer magic. Goal here is to set up req->vwv and
2085 * req->buf correctly again to be able to call the subsequent
2086 * switch_message(). The chain offset (the former vwv[1]) points at
2087 * the new wct field.
2090 wct = CVAL(smb_base(req->inbuf), chain_offset);
2093 * Next consistency check: Make the new vwv array fits in the overall
2094 * smb request.
2097 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2098 if (length_needed > smblen) {
2099 goto error;
2101 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2104 * Now grab the new byte buffer....
2107 buflen = SVAL(vwv+wct, 0);
2110 * .. and check that it fits.
2113 length_needed += buflen;
2114 if (length_needed > smblen) {
2115 goto error;
2117 buf = (const uint8_t *)(vwv+wct+1);
2119 req->cmd = chain_cmd;
2120 req->wct = wct;
2121 req->vwv = discard_const_p(uint16_t, vwv);
2122 req->buflen = buflen;
2123 req->buf = buf;
2125 switch_message(chain_cmd, req, smblen);
2127 if (req->outbuf == NULL) {
2129 * This happens if the chained command has suspended itself or
2130 * if it has called srv_send_smb() itself.
2132 return;
2136 * We end up here if the chained command was not itself chained or
2137 * suspended, but for example a close() command. We now need to splice
2138 * the chained commands' outbuf into the already built up chain_outbuf
2139 * and ship the result.
2141 goto done;
2143 error:
2145 * We end up here if there's any error in the chain syntax. Report a
2146 * DOS error, just like Windows does.
2148 reply_force_doserror(req, ERRSRV, ERRerror);
2149 fixup_chain_error_packet(req);
2151 done:
2153 * This scary statement intends to set the
2154 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2155 * to the value req->outbuf carries
2157 SSVAL(req->chain_outbuf, smb_flg2,
2158 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2159 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2162 * Transfer the error codes from the subrequest to the main one
2164 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2165 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2167 if (!smb_splice_chain(&req->chain_outbuf,
2168 CVAL(req->outbuf, smb_com),
2169 CVAL(req->outbuf, smb_wct),
2170 (uint16_t *)(req->outbuf + smb_vwv),
2171 0, smb_buflen(req->outbuf),
2172 (uint8_t *)smb_buf(req->outbuf))) {
2173 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2175 TALLOC_FREE(req->outbuf);
2177 smb_setlen((char *)(req->chain_outbuf),
2178 talloc_get_size(req->chain_outbuf) - 4);
2180 show_msg((char *)(req->chain_outbuf));
2182 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2183 true, req->seqnum+1,
2184 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2185 &req->pcd)) {
2186 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2188 TALLOC_FREE(req->chain_outbuf);
2189 req->done = true;
2192 /****************************************************************************
2193 Check if services need reloading.
2194 ****************************************************************************/
2196 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2199 if (last_smb_conf_reload_time == 0) {
2200 last_smb_conf_reload_time = t;
2203 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2204 reload_services(sconn->msg_ctx, sconn->sock, True);
2205 last_smb_conf_reload_time = t;
2209 static bool fd_is_readable(int fd)
2211 int ret, revents;
2213 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2215 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2219 static void smbd_server_connection_write_handler(
2220 struct smbd_server_connection *sconn)
2222 /* TODO: make write nonblocking */
2225 static void smbd_server_connection_read_handler(
2226 struct smbd_server_connection *sconn, int fd)
2228 uint8_t *inbuf = NULL;
2229 size_t inbuf_len = 0;
2230 size_t unread_bytes = 0;
2231 bool encrypted = false;
2232 TALLOC_CTX *mem_ctx = talloc_tos();
2233 NTSTATUS status;
2234 uint32_t seqnum;
2236 bool from_client;
2238 if (lp_async_smb_echo_handler()
2239 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2241 * This is the super-ugly hack to prefer the packets
2242 * forwarded by the echo handler over the ones by the
2243 * client directly
2245 fd = sconn->smb1.echo_handler.trusted_fd;
2248 from_client = (sconn->sock == fd);
2250 if (from_client) {
2251 smbd_lock_socket(sconn);
2253 if (!fd_is_readable(fd)) {
2254 DEBUG(10,("the echo listener was faster\n"));
2255 smbd_unlock_socket(sconn);
2256 return;
2260 /* TODO: make this completely nonblocking */
2261 status = receive_smb_talloc(mem_ctx, sconn, fd,
2262 (char **)(void *)&inbuf,
2263 0, /* timeout */
2264 &unread_bytes,
2265 &encrypted,
2266 &inbuf_len, &seqnum,
2267 false /* trusted channel */);
2269 if (from_client) {
2270 smbd_unlock_socket(sconn);
2273 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2274 goto process;
2276 if (NT_STATUS_IS_ERR(status)) {
2277 exit_server_cleanly("failed to receive smb request");
2279 if (!NT_STATUS_IS_OK(status)) {
2280 return;
2283 process:
2284 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2285 seqnum, encrypted, NULL);
2288 static void smbd_server_connection_handler(struct event_context *ev,
2289 struct fd_event *fde,
2290 uint16_t flags,
2291 void *private_data)
2293 struct smbd_server_connection *conn = talloc_get_type(private_data,
2294 struct smbd_server_connection);
2296 if (flags & EVENT_FD_WRITE) {
2297 smbd_server_connection_write_handler(conn);
2298 return;
2300 if (flags & EVENT_FD_READ) {
2301 smbd_server_connection_read_handler(conn, conn->sock);
2302 return;
2306 static void smbd_server_echo_handler(struct event_context *ev,
2307 struct fd_event *fde,
2308 uint16_t flags,
2309 void *private_data)
2311 struct smbd_server_connection *conn = talloc_get_type(private_data,
2312 struct smbd_server_connection);
2314 if (flags & EVENT_FD_WRITE) {
2315 smbd_server_connection_write_handler(conn);
2316 return;
2318 if (flags & EVENT_FD_READ) {
2319 smbd_server_connection_read_handler(
2320 conn, conn->smb1.echo_handler.trusted_fd);
2321 return;
2325 #ifdef CLUSTER_SUPPORT
2326 /****************************************************************************
2327 received when we should release a specific IP
2328 ****************************************************************************/
2329 static void release_ip(const char *ip, void *priv)
2331 const char *addr = (const char *)priv;
2332 const char *p = addr;
2334 if (strncmp("::ffff:", addr, 7) == 0) {
2335 p = addr + 7;
2338 DEBUG(10, ("Got release IP message for %s, "
2339 "our address is %s\n", ip, p));
2341 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2342 /* we can't afford to do a clean exit - that involves
2343 database writes, which would potentially mean we
2344 are still running after the failover has finished -
2345 we have to get rid of this process ID straight
2346 away */
2347 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2348 ip));
2349 /* note we must exit with non-zero status so the unclean handler gets
2350 called in the parent, so that the brl database is tickled */
2351 _exit(1);
2355 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2356 struct sockaddr_storage *client)
2358 socklen_t length;
2359 length = sizeof(*server);
2360 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2361 return -1;
2363 length = sizeof(*client);
2364 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2365 return -1;
2367 return 0;
2369 #endif
2372 * Send keepalive packets to our client
2374 static bool keepalive_fn(const struct timeval *now, void *private_data)
2376 struct smbd_server_connection *sconn = talloc_get_type_abort(
2377 private_data, struct smbd_server_connection);
2378 bool ret;
2380 if (sconn->using_smb2) {
2381 /* Don't do keepalives on an SMB2 connection. */
2382 return false;
2385 smbd_lock_socket(sconn);
2386 ret = send_keepalive(sconn->sock);
2387 smbd_unlock_socket(sconn);
2389 if (!ret) {
2390 char addr[INET6_ADDRSTRLEN];
2392 * Try and give an error message saying what
2393 * client failed.
2395 DEBUG(0, ("send_keepalive failed for client %s. "
2396 "Error %s - exiting\n",
2397 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2398 strerror(errno)));
2399 return False;
2401 return True;
2405 * Do the recurring check if we're idle
2407 static bool deadtime_fn(const struct timeval *now, void *private_data)
2409 struct smbd_server_connection *sconn =
2410 (struct smbd_server_connection *)private_data;
2412 if ((conn_num_open(sconn) == 0)
2413 || (conn_idle_all(sconn, now->tv_sec))) {
2414 DEBUG( 2, ( "Closing idle connection\n" ) );
2415 messaging_send(sconn->msg_ctx,
2416 messaging_server_id(sconn->msg_ctx),
2417 MSG_SHUTDOWN, &data_blob_null);
2418 return False;
2421 return True;
2425 * Do the recurring log file and smb.conf reload checks.
2428 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2430 struct smbd_server_connection *sconn = talloc_get_type_abort(
2431 private_data, struct smbd_server_connection);
2433 DEBUG(5, ("housekeeping\n"));
2435 change_to_root_user();
2437 /* update printer queue caches if necessary */
2438 update_monitored_printq_cache(sconn->msg_ctx);
2440 /* check if we need to reload services */
2441 check_reload(sconn, time_mono(NULL));
2443 /* Change machine password if neccessary. */
2444 attempt_machine_password_change();
2447 * Force a log file check.
2449 force_check_log_size();
2450 check_log_size();
2451 return true;
2455 * Read an smb packet in the echo handler child, giving the parent
2456 * smbd one second to react once the socket becomes readable.
2459 struct smbd_echo_read_state {
2460 struct tevent_context *ev;
2461 struct smbd_server_connection *sconn;
2463 char *buf;
2464 size_t buflen;
2465 uint32_t seqnum;
2468 static void smbd_echo_read_readable(struct tevent_req *subreq);
2469 static void smbd_echo_read_waited(struct tevent_req *subreq);
2471 static struct tevent_req *smbd_echo_read_send(
2472 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2473 struct smbd_server_connection *sconn)
2475 struct tevent_req *req, *subreq;
2476 struct smbd_echo_read_state *state;
2478 req = tevent_req_create(mem_ctx, &state,
2479 struct smbd_echo_read_state);
2480 if (req == NULL) {
2481 return NULL;
2483 state->ev = ev;
2484 state->sconn = sconn;
2486 subreq = wait_for_read_send(state, ev, sconn->sock);
2487 if (tevent_req_nomem(subreq, req)) {
2488 return tevent_req_post(req, ev);
2490 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2491 return req;
2494 static void smbd_echo_read_readable(struct tevent_req *subreq)
2496 struct tevent_req *req = tevent_req_callback_data(
2497 subreq, struct tevent_req);
2498 struct smbd_echo_read_state *state = tevent_req_data(
2499 req, struct smbd_echo_read_state);
2500 bool ok;
2501 int err;
2503 ok = wait_for_read_recv(subreq, &err);
2504 TALLOC_FREE(subreq);
2505 if (!ok) {
2506 tevent_req_nterror(req, map_nt_error_from_unix(err));
2507 return;
2511 * Give the parent smbd one second to step in
2514 subreq = tevent_wakeup_send(
2515 state, state->ev, timeval_current_ofs(1, 0));
2516 if (tevent_req_nomem(subreq, req)) {
2517 return;
2519 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2522 static void smbd_echo_read_waited(struct tevent_req *subreq)
2524 struct tevent_req *req = tevent_req_callback_data(
2525 subreq, struct tevent_req);
2526 struct smbd_echo_read_state *state = tevent_req_data(
2527 req, struct smbd_echo_read_state);
2528 struct smbd_server_connection *sconn = state->sconn;
2529 bool ok;
2530 NTSTATUS status;
2531 size_t unread = 0;
2532 bool encrypted;
2534 ok = tevent_wakeup_recv(subreq);
2535 TALLOC_FREE(subreq);
2536 if (!ok) {
2537 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2538 return;
2541 ok = smbd_lock_socket_internal(sconn);
2542 if (!ok) {
2543 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2544 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2545 return;
2548 if (!fd_is_readable(sconn->sock)) {
2549 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2550 (int)sys_getpid()));
2552 ok = smbd_unlock_socket_internal(sconn);
2553 if (!ok) {
2554 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2555 DEBUG(1, ("%s: failed to unlock socket\n",
2556 __location__));
2557 return;
2560 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2561 if (tevent_req_nomem(subreq, req)) {
2562 return;
2564 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2565 return;
2568 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2569 0 /* timeout */,
2570 &unread,
2571 &encrypted,
2572 &state->buflen,
2573 &state->seqnum,
2574 false /* trusted_channel*/);
2576 if (tevent_req_nterror(req, status)) {
2577 tevent_req_nterror(req, status);
2578 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2579 (int)sys_getpid(), nt_errstr(status)));
2580 return;
2583 ok = smbd_unlock_socket_internal(sconn);
2584 if (!ok) {
2585 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2586 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2587 return;
2589 tevent_req_done(req);
2592 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2593 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2595 struct smbd_echo_read_state *state = tevent_req_data(
2596 req, struct smbd_echo_read_state);
2597 NTSTATUS status;
2599 if (tevent_req_is_nterror(req, &status)) {
2600 return status;
2602 *pbuf = talloc_move(mem_ctx, &state->buf);
2603 *pbuflen = state->buflen;
2604 *pseqnum = state->seqnum;
2605 return NT_STATUS_OK;
2608 struct smbd_echo_state {
2609 struct tevent_context *ev;
2610 struct iovec *pending;
2611 struct smbd_server_connection *sconn;
2612 int parent_pipe;
2614 struct tevent_fd *parent_fde;
2616 struct tevent_req *write_req;
2619 static void smbd_echo_writer_done(struct tevent_req *req);
2621 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2623 int num_pending;
2625 if (state->write_req != NULL) {
2626 return;
2629 num_pending = talloc_array_length(state->pending);
2630 if (num_pending == 0) {
2631 return;
2634 state->write_req = writev_send(state, state->ev, NULL,
2635 state->parent_pipe, false,
2636 state->pending, num_pending);
2637 if (state->write_req == NULL) {
2638 DEBUG(1, ("writev_send failed\n"));
2639 exit(1);
2642 talloc_steal(state->write_req, state->pending);
2643 state->pending = NULL;
2645 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2646 state);
2649 static void smbd_echo_writer_done(struct tevent_req *req)
2651 struct smbd_echo_state *state = tevent_req_callback_data(
2652 req, struct smbd_echo_state);
2653 ssize_t written;
2654 int err;
2656 written = writev_recv(req, &err);
2657 TALLOC_FREE(req);
2658 state->write_req = NULL;
2659 if (written == -1) {
2660 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2661 exit(1);
2663 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2664 smbd_echo_activate_writer(state);
2667 static bool smbd_echo_reply(struct smbd_echo_state *state,
2668 uint8_t *inbuf, size_t inbuf_len,
2669 uint32_t seqnum)
2671 struct smb_request req;
2672 uint16_t num_replies;
2673 size_t out_len;
2674 char *outbuf;
2675 bool ok;
2677 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2678 DEBUG(10, ("Got netbios keepalive\n"));
2680 * Just swallow it
2682 return true;
2685 if (inbuf_len < smb_size) {
2686 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2687 return false;
2689 if (!valid_smb_header(state->sconn, inbuf)) {
2690 DEBUG(10, ("Got invalid SMB header\n"));
2691 return false;
2694 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2695 seqnum)) {
2696 return false;
2698 req.inbuf = inbuf;
2700 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2701 smb_messages[req.cmd].name
2702 ? smb_messages[req.cmd].name : "unknown"));
2704 if (req.cmd != SMBecho) {
2705 return false;
2707 if (req.wct < 1) {
2708 return false;
2711 num_replies = SVAL(req.vwv+0, 0);
2712 if (num_replies != 1) {
2713 /* Not a Windows "Hey, you're still there?" request */
2714 return false;
2717 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2718 1, req.buflen)) {
2719 DEBUG(10, ("create_outbuf failed\n"));
2720 return false;
2722 req.outbuf = (uint8_t *)outbuf;
2724 SSVAL(req.outbuf, smb_vwv0, num_replies);
2726 if (req.buflen > 0) {
2727 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2730 out_len = smb_len(req.outbuf) + 4;
2732 ok = srv_send_smb(req.sconn,
2733 (char *)outbuf,
2734 true, seqnum+1,
2735 false, &req.pcd);
2736 TALLOC_FREE(outbuf);
2737 if (!ok) {
2738 exit(1);
2741 return true;
2744 static void smbd_echo_exit(struct tevent_context *ev,
2745 struct tevent_fd *fde, uint16_t flags,
2746 void *private_data)
2748 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2749 exit(0);
2752 static void smbd_echo_got_packet(struct tevent_req *req);
2754 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2755 int parent_pipe)
2757 struct smbd_echo_state *state;
2758 struct tevent_req *read_req;
2760 state = talloc_zero(sconn, struct smbd_echo_state);
2761 if (state == NULL) {
2762 DEBUG(1, ("talloc failed\n"));
2763 return;
2765 state->sconn = sconn;
2766 state->parent_pipe = parent_pipe;
2767 state->ev = s3_tevent_context_init(state);
2768 if (state->ev == NULL) {
2769 DEBUG(1, ("tevent_context_init failed\n"));
2770 TALLOC_FREE(state);
2771 return;
2773 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2774 TEVENT_FD_READ, smbd_echo_exit,
2775 state);
2776 if (state->parent_fde == NULL) {
2777 DEBUG(1, ("tevent_add_fd failed\n"));
2778 TALLOC_FREE(state);
2779 return;
2782 read_req = smbd_echo_read_send(state, state->ev, sconn);
2783 if (read_req == NULL) {
2784 DEBUG(1, ("smbd_echo_read_send failed\n"));
2785 TALLOC_FREE(state);
2786 return;
2788 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2790 while (true) {
2791 if (tevent_loop_once(state->ev) == -1) {
2792 DEBUG(1, ("tevent_loop_once failed: %s\n",
2793 strerror(errno)));
2794 break;
2797 TALLOC_FREE(state);
2800 static void smbd_echo_got_packet(struct tevent_req *req)
2802 struct smbd_echo_state *state = tevent_req_callback_data(
2803 req, struct smbd_echo_state);
2804 NTSTATUS status;
2805 char *buf = NULL;
2806 size_t buflen = 0;
2807 uint32_t seqnum = 0;
2808 bool reply;
2810 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2811 TALLOC_FREE(req);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2814 nt_errstr(status)));
2815 exit(1);
2818 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2819 if (!reply) {
2820 size_t num_pending;
2821 struct iovec *tmp;
2822 struct iovec *iov;
2824 num_pending = talloc_array_length(state->pending);
2825 tmp = talloc_realloc(state, state->pending, struct iovec,
2826 num_pending+1);
2827 if (tmp == NULL) {
2828 DEBUG(1, ("talloc_realloc failed\n"));
2829 exit(1);
2831 state->pending = tmp;
2833 if (buflen >= smb_size) {
2835 * place the seqnum in the packet so that the main process
2836 * can reply with signing
2838 SIVAL(buf, smb_ss_field, seqnum);
2839 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2842 iov = &state->pending[num_pending];
2843 iov->iov_base = buf;
2844 iov->iov_len = buflen;
2846 DEBUG(10,("echo_handler[%d]: forward to main\n",
2847 (int)sys_getpid()));
2848 smbd_echo_activate_writer(state);
2851 req = smbd_echo_read_send(state, state->ev, state->sconn);
2852 if (req == NULL) {
2853 DEBUG(1, ("smbd_echo_read_send failed\n"));
2854 exit(1);
2856 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2861 * Handle SMBecho requests in a forked child process
2863 bool fork_echo_handler(struct smbd_server_connection *sconn)
2865 int listener_pipe[2];
2866 int res;
2867 pid_t child;
2869 res = pipe(listener_pipe);
2870 if (res == -1) {
2871 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2872 return false;
2874 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2875 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2876 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2877 goto fail;
2880 child = sys_fork();
2881 if (child == 0) {
2882 NTSTATUS status;
2884 close(listener_pipe[0]);
2885 set_blocking(listener_pipe[1], false);
2887 status = reinit_after_fork(sconn->msg_ctx,
2888 sconn->ev_ctx,
2889 false);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 DEBUG(1, ("reinit_after_fork failed: %s\n",
2892 nt_errstr(status)));
2893 exit(1);
2895 smbd_echo_loop(sconn, listener_pipe[1]);
2896 exit(0);
2898 close(listener_pipe[1]);
2899 listener_pipe[1] = -1;
2900 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2902 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2905 * Without smb signing this is the same as the normal smbd
2906 * listener. This needs to change once signing comes in.
2908 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2909 sconn,
2910 sconn->smb1.echo_handler.trusted_fd,
2911 TEVENT_FD_READ,
2912 smbd_server_echo_handler,
2913 sconn);
2914 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2915 DEBUG(1, ("event_add_fd failed\n"));
2916 goto fail;
2919 return true;
2921 fail:
2922 if (listener_pipe[0] != -1) {
2923 close(listener_pipe[0]);
2925 if (listener_pipe[1] != -1) {
2926 close(listener_pipe[1]);
2928 sconn->smb1.echo_handler.trusted_fd = -1;
2929 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2930 close(sconn->smb1.echo_handler.socket_lock_fd);
2932 sconn->smb1.echo_handler.trusted_fd = -1;
2933 sconn->smb1.echo_handler.socket_lock_fd = -1;
2934 return false;
2937 #if CLUSTER_SUPPORT
2939 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2940 struct sockaddr_storage *srv,
2941 struct sockaddr_storage *clnt)
2943 struct ctdbd_connection *cconn;
2944 char tmp_addr[INET6_ADDRSTRLEN];
2945 char *addr;
2947 cconn = messaging_ctdbd_connection();
2948 if (cconn == NULL) {
2949 return NT_STATUS_NO_MEMORY;
2952 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2953 addr = talloc_strdup(cconn, tmp_addr);
2954 if (addr == NULL) {
2955 return NT_STATUS_NO_MEMORY;
2957 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2960 #endif
2962 /****************************************************************************
2963 Process commands from the client
2964 ****************************************************************************/
2966 void smbd_process(struct tevent_context *ev_ctx,
2967 struct smbd_server_connection *sconn)
2969 TALLOC_CTX *frame = talloc_stackframe();
2970 struct sockaddr_storage ss;
2971 struct sockaddr *sa = NULL;
2972 socklen_t sa_socklen;
2973 struct tsocket_address *local_address = NULL;
2974 struct tsocket_address *remote_address = NULL;
2975 const char *locaddr = NULL;
2976 const char *remaddr = NULL;
2977 char *rhost;
2978 int ret;
2980 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2982 * We're not making the decision here,
2983 * we're just allowing the client
2984 * to decide between SMB1 and SMB2
2985 * with the first negprot
2986 * packet.
2988 sconn->using_smb2 = true;
2991 /* Ensure child is set to blocking mode */
2992 set_blocking(sconn->sock,True);
2994 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2995 set_socket_options(sconn->sock, lp_socket_options());
2997 sa = (struct sockaddr *)(void *)&ss;
2998 sa_socklen = sizeof(ss);
2999 ret = getpeername(sconn->sock, sa, &sa_socklen);
3000 if (ret != 0) {
3001 int level = (errno == ENOTCONN)?2:0;
3002 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3003 exit_server_cleanly("getpeername() failed.\n");
3005 ret = tsocket_address_bsd_from_sockaddr(sconn,
3006 sa, sa_socklen,
3007 &remote_address);
3008 if (ret != 0) {
3009 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3010 __location__, strerror(errno)));
3011 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3014 sa = (struct sockaddr *)(void *)&ss;
3015 sa_socklen = sizeof(ss);
3016 ret = getsockname(sconn->sock, sa, &sa_socklen);
3017 if (ret != 0) {
3018 int level = (errno == ENOTCONN)?2:0;
3019 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3020 exit_server_cleanly("getsockname() failed.\n");
3022 ret = tsocket_address_bsd_from_sockaddr(sconn,
3023 sa, sa_socklen,
3024 &local_address);
3025 if (ret != 0) {
3026 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3027 __location__, strerror(errno)));
3028 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3031 sconn->local_address = local_address;
3032 sconn->remote_address = remote_address;
3034 if (tsocket_address_is_inet(local_address, "ip")) {
3035 locaddr = tsocket_address_inet_addr_string(
3036 sconn->local_address,
3037 talloc_tos());
3038 if (locaddr == NULL) {
3039 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3040 __location__, strerror(errno)));
3041 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3043 } else {
3044 locaddr = "0.0.0.0";
3047 if (tsocket_address_is_inet(remote_address, "ip")) {
3048 remaddr = tsocket_address_inet_addr_string(
3049 sconn->remote_address,
3050 talloc_tos());
3051 if (remaddr == NULL) {
3052 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3053 __location__, strerror(errno)));
3054 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3056 } else {
3057 remaddr = "0.0.0.0";
3060 /* this is needed so that we get decent entries
3061 in smbstatus for port 445 connects */
3062 set_remote_machine_name(remaddr, false);
3063 reload_services(sconn->msg_ctx, sconn->sock, true);
3066 * Before the first packet, check the global hosts allow/ hosts deny
3067 * parameters before doing any parsing of packets passed to us by the
3068 * client. This prevents attacks on our parsing code from hosts not in
3069 * the hosts allow list.
3072 ret = get_remote_hostname(remote_address,
3073 &rhost,
3074 talloc_tos());
3075 if (ret < 0) {
3076 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3077 __location__, strerror(errno)));
3078 exit_server_cleanly("get_remote_hostname failed.\n");
3080 if (strequal(rhost, "UNKNOWN")) {
3081 rhost = talloc_strdup(talloc_tos(), remaddr);
3083 sconn->remote_hostname = talloc_move(sconn, &rhost);
3085 sub_set_socket_ids(remaddr,
3086 sconn->remote_hostname,
3087 locaddr);
3089 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3090 sconn->remote_hostname,
3091 remaddr)) {
3093 * send a negative session response "not listening on calling
3094 * name"
3096 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3097 DEBUG( 1, ("Connection denied from %s to %s\n",
3098 tsocket_address_string(remote_address, talloc_tos()),
3099 tsocket_address_string(local_address, talloc_tos())));
3100 (void)srv_send_smb(sconn,(char *)buf, false,
3101 0, false, NULL);
3102 exit_server_cleanly("connection denied");
3105 DEBUG(10, ("Connection allowed from %s to %s\n",
3106 tsocket_address_string(remote_address, talloc_tos()),
3107 tsocket_address_string(local_address, talloc_tos())));
3109 init_modules();
3111 smb_perfcount_init();
3113 if (!init_account_policy()) {
3114 exit_server("Could not open account policy tdb.\n");
3117 if (*lp_rootdir()) {
3118 if (chroot(lp_rootdir()) != 0) {
3119 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3120 exit_server("Failed to chroot()");
3122 if (chdir("/") == -1) {
3123 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3124 exit_server("Failed to chroot()");
3126 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3129 if (!srv_init_signing(sconn)) {
3130 exit_server("Failed to init smb_signing");
3133 /* Setup oplocks */
3134 if (!init_oplocks(sconn->msg_ctx))
3135 exit_server("Failed to init oplocks");
3137 /* register our message handlers */
3138 messaging_register(sconn->msg_ctx, NULL,
3139 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3140 messaging_register(sconn->msg_ctx, sconn,
3141 MSG_SMB_CLOSE_FILE, msg_close_file);
3144 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3145 * MSGs to all child processes
3147 messaging_deregister(sconn->msg_ctx,
3148 MSG_DEBUG, NULL);
3149 messaging_register(sconn->msg_ctx, NULL,
3150 MSG_DEBUG, debug_message);
3152 if ((lp_keepalive() != 0)
3153 && !(event_add_idle(ev_ctx, NULL,
3154 timeval_set(lp_keepalive(), 0),
3155 "keepalive", keepalive_fn,
3156 sconn))) {
3157 DEBUG(0, ("Could not add keepalive event\n"));
3158 exit(1);
3161 if (!(event_add_idle(ev_ctx, NULL,
3162 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3163 "deadtime", deadtime_fn, sconn))) {
3164 DEBUG(0, ("Could not add deadtime event\n"));
3165 exit(1);
3168 if (!(event_add_idle(ev_ctx, NULL,
3169 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3170 "housekeeping", housekeeping_fn, sconn))) {
3171 DEBUG(0, ("Could not add housekeeping event\n"));
3172 exit(1);
3175 #ifdef CLUSTER_SUPPORT
3177 if (lp_clustering()) {
3179 * We need to tell ctdb about our client's TCP
3180 * connection, so that for failover ctdbd can send
3181 * tickle acks, triggering a reconnection by the
3182 * client.
3185 struct sockaddr_storage srv, clnt;
3187 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3188 NTSTATUS status;
3189 status = smbd_register_ips(sconn, &srv, &clnt);
3190 if (!NT_STATUS_IS_OK(status)) {
3191 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3192 nt_errstr(status)));
3194 } else
3196 DEBUG(0,("Unable to get tcp info for "
3197 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3198 strerror(errno)));
3202 #endif
3204 sconn->nbt.got_session = false;
3206 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3208 sconn->smb1.sessions.done_sesssetup = false;
3209 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3210 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3211 /* users from session setup */
3212 sconn->smb1.sessions.session_userlist = NULL;
3213 /* workgroup from session setup. */
3214 sconn->smb1.sessions.session_workgroup = NULL;
3215 /* this holds info on user ids that are already validated for this VC */
3216 sconn->smb1.sessions.validated_users = NULL;
3217 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3218 sconn->smb1.sessions.num_validated_vuids = 0;
3220 conn_init(sconn);
3221 if (!init_dptrs(sconn)) {
3222 exit_server("init_dptrs() failed");
3225 sconn->smb1.fde = event_add_fd(ev_ctx,
3226 sconn,
3227 sconn->sock,
3228 EVENT_FD_READ,
3229 smbd_server_connection_handler,
3230 sconn);
3231 if (!sconn->smb1.fde) {
3232 exit_server("failed to create smbd_server_connection fde");
3235 TALLOC_FREE(frame);
3237 while (True) {
3238 NTSTATUS status;
3240 frame = talloc_stackframe_pool(8192);
3242 errno = 0;
3244 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3245 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3246 !NT_STATUS_IS_OK(status)) {
3247 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3248 " exiting\n", nt_errstr(status)));
3249 break;
3252 TALLOC_FREE(frame);
3255 exit_server_cleanly(NULL);
3258 bool req_is_in_chain(struct smb_request *req)
3260 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3262 * We're right now handling a subsequent request, so we must
3263 * be in a chain
3265 return true;
3268 if (!is_andx_req(req->cmd)) {
3269 return false;
3272 if (req->wct < 2) {
3274 * Okay, an illegal request, but definitely not chained :-)
3276 return false;
3279 return (CVAL(req->vwv+0, 0) != 0xFF);