s3: Handle EINTR from sys_poll correctly
[Samba.git] / source3 / smbd / process.c
blob169c45953466f929044d8184950f52c8097a2076
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/pcap.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"
38 extern bool global_machine_password_needs_changing;
40 static void construct_reply_common(struct smb_request *req, const char *inbuf,
41 char *outbuf);
42 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
44 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
46 bool ok;
48 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
49 return true;
52 sconn->smb1.echo_handler.ref_count++;
54 if (sconn->smb1.echo_handler.ref_count > 1) {
55 return true;
58 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
60 do {
61 ok = fcntl_lock(
62 sconn->smb1.echo_handler.socket_lock_fd,
63 SMB_F_SETLKW, 0, 0, F_WRLCK);
64 } while (!ok && (errno == EINTR));
66 if (!ok) {
67 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
68 return false;
71 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
73 return true;
76 void smbd_lock_socket(struct smbd_server_connection *sconn)
78 if (!smbd_lock_socket_internal(sconn)) {
79 exit_server_cleanly("failed to lock socket");
83 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
85 bool ok;
87 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
88 return true;
91 sconn->smb1.echo_handler.ref_count--;
93 if (sconn->smb1.echo_handler.ref_count > 0) {
94 return true;
97 do {
98 ok = fcntl_lock(
99 sconn->smb1.echo_handler.socket_lock_fd,
100 SMB_F_SETLKW, 0, 0, F_UNLCK);
101 } while (!ok && (errno == EINTR));
103 if (!ok) {
104 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
105 return false;
108 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
110 return true;
113 void smbd_unlock_socket(struct smbd_server_connection *sconn)
115 if (!smbd_unlock_socket_internal(sconn)) {
116 exit_server_cleanly("failed to unlock socket");
120 /* Accessor function for smb_read_error for smbd functions. */
122 /****************************************************************************
123 Send an smb to a fd.
124 ****************************************************************************/
126 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
127 bool do_signing, uint32_t seqnum,
128 bool do_encrypt,
129 struct smb_perfcount_data *pcd)
131 size_t len = 0;
132 size_t nwritten=0;
133 ssize_t ret;
134 char *buf_out = buffer;
136 smbd_lock_socket(sconn);
138 if (do_signing) {
139 /* Sign the outgoing packet if required. */
140 srv_calculate_sign_mac(sconn, buf_out, seqnum);
143 if (do_encrypt) {
144 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
145 if (!NT_STATUS_IS_OK(status)) {
146 DEBUG(0, ("send_smb: SMB encryption failed "
147 "on outgoing packet! Error %s\n",
148 nt_errstr(status) ));
149 goto out;
153 len = smb_len(buf_out) + 4;
155 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
156 if (ret <= 0) {
158 char addr[INET6_ADDRSTRLEN];
160 * Try and give an error message saying what
161 * client failed.
163 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
164 (int)sys_getpid(), (int)len,
165 get_peer_addr(sconn->sock, addr, sizeof(addr)),
166 (int)ret, strerror(errno) ));
168 srv_free_enc_buffer(buf_out);
169 goto out;
172 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
173 srv_free_enc_buffer(buf_out);
174 out:
175 SMB_PERFCOUNT_END(pcd);
177 smbd_unlock_socket(sconn);
178 return true;
181 /*******************************************************************
182 Setup the word count and byte count for a smb message.
183 ********************************************************************/
185 int srv_set_message(char *buf,
186 int num_words,
187 int num_bytes,
188 bool zero)
190 if (zero && (num_words || num_bytes)) {
191 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
193 SCVAL(buf,smb_wct,num_words);
194 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
195 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
196 return (smb_size + num_words*2 + num_bytes);
199 static bool valid_smb_header(const uint8_t *inbuf)
201 if (is_encrypted_packet(inbuf)) {
202 return true;
205 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
206 * but it just looks weird to call strncmp for this one.
208 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
211 /* Socket functions for smbd packet processing. */
213 static bool valid_packet_size(size_t len)
216 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
217 * of header. Don't print the error if this fits.... JRA.
220 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
221 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
222 (unsigned long)len));
223 return false;
225 return true;
228 static NTSTATUS read_packet_remainder(int fd, char *buffer,
229 unsigned int timeout, ssize_t len)
231 NTSTATUS status;
233 if (len <= 0) {
234 return NT_STATUS_OK;
237 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
238 if (!NT_STATUS_IS_OK(status)) {
239 char addr[INET6_ADDRSTRLEN];
240 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
241 "error = %s.\n",
242 get_peer_addr(fd, addr, sizeof(addr)),
243 nt_errstr(status)));
245 return status;
248 /****************************************************************************
249 Attempt a zerocopy writeX read. We know here that len > smb_size-4
250 ****************************************************************************/
253 * Unfortunately, earlier versions of smbclient/libsmbclient
254 * don't send this "standard" writeX header. I've fixed this
255 * for 3.2 but we'll use the old method with earlier versions.
256 * Windows and CIFSFS at least use this standard size. Not
257 * sure about MacOSX.
260 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
261 (2*14) + /* word count (including bcc) */ \
262 1 /* pad byte */)
264 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
265 const char lenbuf[4],
266 struct smbd_server_connection *sconn,
267 int sock,
268 char **buffer,
269 unsigned int timeout,
270 size_t *p_unread,
271 size_t *len_ret)
273 /* Size of a WRITEX call (+4 byte len). */
274 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
275 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
276 ssize_t toread;
277 NTSTATUS status;
279 memcpy(writeX_header, lenbuf, 4);
281 status = read_fd_with_timeout(
282 sock, writeX_header + 4,
283 STANDARD_WRITE_AND_X_HEADER_SIZE,
284 STANDARD_WRITE_AND_X_HEADER_SIZE,
285 timeout, NULL);
287 if (!NT_STATUS_IS_OK(status)) {
288 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
289 "error = %s.\n", sconn->client_id.addr,
290 nt_errstr(status)));
291 return status;
295 * Ok - now try and see if this is a possible
296 * valid writeX call.
299 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
301 * If the data offset is beyond what
302 * we've read, drain the extra bytes.
304 uint16_t doff = SVAL(writeX_header,smb_vwv11);
305 ssize_t newlen;
307 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
308 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
309 if (drain_socket(sock, drain) != drain) {
310 smb_panic("receive_smb_raw_talloc_partial_read:"
311 " failed to drain pending bytes");
313 } else {
314 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
317 /* Spoof down the length and null out the bcc. */
318 set_message_bcc(writeX_header, 0);
319 newlen = smb_len(writeX_header);
321 /* Copy the header we've written. */
323 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
324 writeX_header,
325 sizeof(writeX_header));
327 if (*buffer == NULL) {
328 DEBUG(0, ("Could not allocate inbuf of length %d\n",
329 (int)sizeof(writeX_header)));
330 return NT_STATUS_NO_MEMORY;
333 /* Work out the remaining bytes. */
334 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
335 *len_ret = newlen + 4;
336 return NT_STATUS_OK;
339 if (!valid_packet_size(len)) {
340 return NT_STATUS_INVALID_PARAMETER;
344 * Not a valid writeX call. Just do the standard
345 * talloc and return.
348 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
350 if (*buffer == NULL) {
351 DEBUG(0, ("Could not allocate inbuf of length %d\n",
352 (int)len+4));
353 return NT_STATUS_NO_MEMORY;
356 /* Copy in what we already read. */
357 memcpy(*buffer,
358 writeX_header,
359 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
360 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
362 if(toread > 0) {
363 status = read_packet_remainder(
364 sock,
365 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
366 timeout, toread);
368 if (!NT_STATUS_IS_OK(status)) {
369 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
370 nt_errstr(status)));
371 return status;
375 *len_ret = len + 4;
376 return NT_STATUS_OK;
379 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
380 struct smbd_server_connection *sconn,
381 int sock,
382 char **buffer, unsigned int timeout,
383 size_t *p_unread, size_t *plen)
385 char lenbuf[4];
386 size_t len;
387 int min_recv_size = lp_min_receive_file_size();
388 NTSTATUS status;
390 *p_unread = 0;
392 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
393 &len);
394 if (!NT_STATUS_IS_OK(status)) {
395 return status;
398 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
399 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
400 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
401 !srv_is_signing_active(sconn) &&
402 sconn->smb1.echo_handler.trusted_fde == NULL) {
404 return receive_smb_raw_talloc_partial_read(
405 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
406 p_unread, plen);
409 if (!valid_packet_size(len)) {
410 return NT_STATUS_INVALID_PARAMETER;
414 * The +4 here can't wrap, we've checked the length above already.
417 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
419 if (*buffer == NULL) {
420 DEBUG(0, ("Could not allocate inbuf of length %d\n",
421 (int)len+4));
422 return NT_STATUS_NO_MEMORY;
425 memcpy(*buffer, lenbuf, sizeof(lenbuf));
427 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
428 if (!NT_STATUS_IS_OK(status)) {
429 return status;
432 *plen = len + 4;
433 return NT_STATUS_OK;
436 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
437 struct smbd_server_connection *sconn,
438 int sock,
439 char **buffer, unsigned int timeout,
440 size_t *p_unread, bool *p_encrypted,
441 size_t *p_len,
442 uint32_t *seqnum,
443 bool trusted_channel)
445 size_t len = 0;
446 NTSTATUS status;
448 *p_encrypted = false;
450 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
451 p_unread, &len);
452 if (!NT_STATUS_IS_OK(status)) {
453 DEBUG(1, ("read_smb_length_return_keepalive failed for "
454 "client %s read error = %s.\n",
455 sconn->client_id.addr, nt_errstr(status)));
456 return status;
459 if (is_encrypted_packet((uint8_t *)*buffer)) {
460 status = srv_decrypt_buffer(*buffer);
461 if (!NT_STATUS_IS_OK(status)) {
462 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
463 "incoming packet! Error %s\n",
464 nt_errstr(status) ));
465 return status;
467 *p_encrypted = true;
470 /* Check the incoming SMB signature. */
471 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
472 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
473 "incoming packet!\n"));
474 return NT_STATUS_INVALID_NETWORK_RESPONSE;
477 *p_len = len;
478 return NT_STATUS_OK;
482 * Initialize a struct smb_request from an inbuf
485 static bool init_smb_request(struct smb_request *req,
486 struct smbd_server_connection *sconn,
487 const uint8 *inbuf,
488 size_t unread_bytes, bool encrypted,
489 uint32_t seqnum)
491 size_t req_size = smb_len(inbuf) + 4;
492 /* Ensure we have at least smb_size bytes. */
493 if (req_size < smb_size) {
494 DEBUG(0,("init_smb_request: invalid request size %u\n",
495 (unsigned int)req_size ));
496 return false;
498 req->cmd = CVAL(inbuf, smb_com);
499 req->flags2 = SVAL(inbuf, smb_flg2);
500 req->smbpid = SVAL(inbuf, smb_pid);
501 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
502 req->seqnum = seqnum;
503 req->vuid = SVAL(inbuf, smb_uid);
504 req->tid = SVAL(inbuf, smb_tid);
505 req->wct = CVAL(inbuf, smb_wct);
506 req->vwv = (uint16_t *)(inbuf+smb_vwv);
507 req->buflen = smb_buflen(inbuf);
508 req->buf = (const uint8_t *)smb_buf(inbuf);
509 req->unread_bytes = unread_bytes;
510 req->encrypted = encrypted;
511 req->sconn = sconn;
512 req->conn = conn_find(sconn,req->tid);
513 req->chain_fsp = NULL;
514 req->chain_outbuf = NULL;
515 req->done = false;
516 req->smb2req = NULL;
517 smb_init_perfcount_data(&req->pcd);
519 /* Ensure we have at least wct words and 2 bytes of bcc. */
520 if (smb_size + req->wct*2 > req_size) {
521 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
522 (unsigned int)req->wct,
523 (unsigned int)req_size));
524 return false;
526 /* Ensure bcc is correct. */
527 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
528 DEBUG(0,("init_smb_request: invalid bcc number %u "
529 "(wct = %u, size %u)\n",
530 (unsigned int)req->buflen,
531 (unsigned int)req->wct,
532 (unsigned int)req_size));
533 return false;
536 req->outbuf = NULL;
537 return true;
540 static void process_smb(struct smbd_server_connection *conn,
541 uint8_t *inbuf, size_t nread, size_t unread_bytes,
542 uint32_t seqnum, bool encrypted,
543 struct smb_perfcount_data *deferred_pcd);
545 static void smbd_deferred_open_timer(struct event_context *ev,
546 struct timed_event *te,
547 struct timeval _tval,
548 void *private_data)
550 struct pending_message_list *msg = talloc_get_type(private_data,
551 struct pending_message_list);
552 TALLOC_CTX *mem_ctx = talloc_tos();
553 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
554 uint8_t *inbuf;
556 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
557 msg->buf.length);
558 if (inbuf == NULL) {
559 exit_server("smbd_deferred_open_timer: talloc failed\n");
560 return;
563 /* We leave this message on the queue so the open code can
564 know this is a retry. */
565 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
566 (unsigned long long)mid ));
568 /* Mark the message as processed so this is not
569 * re-processed in error. */
570 msg->processed = true;
572 process_smb(smbd_server_conn, inbuf,
573 msg->buf.length, 0,
574 msg->seqnum, msg->encrypted, &msg->pcd);
576 /* If it's still there and was processed, remove it. */
577 msg = get_deferred_open_message_smb(mid);
578 if (msg && msg->processed) {
579 remove_deferred_open_message_smb(mid);
583 /****************************************************************************
584 Function to push a message onto the tail of a linked list of smb messages ready
585 for processing.
586 ****************************************************************************/
588 static bool push_queued_message(struct smb_request *req,
589 struct timeval request_time,
590 struct timeval end_time,
591 char *private_data, size_t private_len)
593 int msg_len = smb_len(req->inbuf) + 4;
594 struct pending_message_list *msg;
596 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
598 if(msg == NULL) {
599 DEBUG(0,("push_message: malloc fail (1)\n"));
600 return False;
603 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
604 if(msg->buf.data == NULL) {
605 DEBUG(0,("push_message: malloc fail (2)\n"));
606 TALLOC_FREE(msg);
607 return False;
610 msg->request_time = request_time;
611 msg->seqnum = req->seqnum;
612 msg->encrypted = req->encrypted;
613 msg->processed = false;
614 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
616 if (private_data) {
617 msg->private_data = data_blob_talloc(msg, private_data,
618 private_len);
619 if (msg->private_data.data == NULL) {
620 DEBUG(0,("push_message: malloc fail (3)\n"));
621 TALLOC_FREE(msg);
622 return False;
626 msg->te = event_add_timed(smbd_event_context(),
627 msg,
628 end_time,
629 smbd_deferred_open_timer,
630 msg);
631 if (!msg->te) {
632 DEBUG(0,("push_message: event_add_timed failed\n"));
633 TALLOC_FREE(msg);
634 return false;
637 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
639 DEBUG(10,("push_message: pushed message length %u on "
640 "deferred_open_queue\n", (unsigned int)msg_len));
642 return True;
645 /****************************************************************************
646 Function to delete a sharing violation open message by mid.
647 ****************************************************************************/
649 void remove_deferred_open_message_smb(uint64_t mid)
651 struct pending_message_list *pml;
653 if (smbd_server_conn->using_smb2) {
654 remove_deferred_open_message_smb2(smbd_server_conn, mid);
655 return;
658 for (pml = deferred_open_queue; pml; pml = pml->next) {
659 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
660 DEBUG(10,("remove_deferred_open_message_smb: "
661 "deleting mid %llu len %u\n",
662 (unsigned long long)mid,
663 (unsigned int)pml->buf.length ));
664 DLIST_REMOVE(deferred_open_queue, pml);
665 TALLOC_FREE(pml);
666 return;
671 /****************************************************************************
672 Move a sharing violation open retry message to the front of the list and
673 schedule it for immediate processing.
674 ****************************************************************************/
676 void schedule_deferred_open_message_smb(uint64_t mid)
678 struct pending_message_list *pml;
679 int i = 0;
681 if (smbd_server_conn->using_smb2) {
682 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
683 return;
686 for (pml = deferred_open_queue; pml; pml = pml->next) {
687 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
689 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
690 "msg_mid = %llu\n",
691 i++,
692 (unsigned long long)msg_mid ));
694 if (mid == msg_mid) {
695 struct timed_event *te;
697 if (pml->processed) {
698 /* A processed message should not be
699 * rescheduled. */
700 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
701 "message mid %llu was already processed\n",
702 (unsigned long long)msg_mid ));
703 continue;
706 DEBUG(10,("schedule_deferred_open_message_smb: "
707 "scheduling mid %llu\n",
708 (unsigned long long)mid ));
710 te = event_add_timed(smbd_event_context(),
711 pml,
712 timeval_zero(),
713 smbd_deferred_open_timer,
714 pml);
715 if (!te) {
716 DEBUG(10,("schedule_deferred_open_message_smb: "
717 "event_add_timed() failed, "
718 "skipping mid %llu\n",
719 (unsigned long long)msg_mid ));
722 TALLOC_FREE(pml->te);
723 pml->te = te;
724 DLIST_PROMOTE(deferred_open_queue, pml);
725 return;
729 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
730 "find message mid %llu\n",
731 (unsigned long long)mid ));
734 /****************************************************************************
735 Return true if this mid is on the deferred queue and was not yet processed.
736 ****************************************************************************/
738 bool open_was_deferred(uint64_t mid)
740 struct pending_message_list *pml;
742 if (smbd_server_conn->using_smb2) {
743 return open_was_deferred_smb2(smbd_server_conn, mid);
746 for (pml = deferred_open_queue; pml; pml = pml->next) {
747 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
748 return True;
751 return False;
754 /****************************************************************************
755 Return the message queued by this mid.
756 ****************************************************************************/
758 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
760 struct pending_message_list *pml;
762 for (pml = deferred_open_queue; pml; pml = pml->next) {
763 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
764 return pml;
767 return NULL;
770 /****************************************************************************
771 Get the state data queued by this mid.
772 ****************************************************************************/
774 bool get_deferred_open_message_state(struct smb_request *smbreq,
775 struct timeval *p_request_time,
776 void **pp_state)
778 struct pending_message_list *pml;
780 if (smbd_server_conn->using_smb2) {
781 return get_deferred_open_message_state_smb2(smbreq->smb2req,
782 p_request_time,
783 pp_state);
786 pml = get_deferred_open_message_smb(smbreq->mid);
787 if (!pml) {
788 return false;
790 if (p_request_time) {
791 *p_request_time = pml->request_time;
793 if (pp_state) {
794 *pp_state = (void *)pml->private_data.data;
796 return true;
799 /****************************************************************************
800 Function to push a deferred open smb message onto a linked list of local smb
801 messages ready for processing.
802 ****************************************************************************/
804 bool push_deferred_open_message_smb(struct smb_request *req,
805 struct timeval request_time,
806 struct timeval timeout,
807 struct file_id id,
808 char *private_data, size_t priv_len)
810 struct timeval end_time;
812 if (req->smb2req) {
813 return push_deferred_open_message_smb2(req->smb2req,
814 request_time,
815 timeout,
817 private_data,
818 priv_len);
821 if (req->unread_bytes) {
822 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
823 "unread_bytes = %u\n",
824 (unsigned int)req->unread_bytes ));
825 smb_panic("push_deferred_open_message_smb: "
826 "logic error unread_bytes != 0" );
829 end_time = timeval_sum(&request_time, &timeout);
831 DEBUG(10,("push_deferred_open_message_smb: pushing message "
832 "len %u mid %llu timeout time [%u.%06u]\n",
833 (unsigned int) smb_len(req->inbuf)+4,
834 (unsigned long long)req->mid,
835 (unsigned int)end_time.tv_sec,
836 (unsigned int)end_time.tv_usec));
838 return push_queued_message(req, request_time, end_time,
839 private_data, priv_len);
842 struct idle_event {
843 struct timed_event *te;
844 struct timeval interval;
845 char *name;
846 bool (*handler)(const struct timeval *now, void *private_data);
847 void *private_data;
850 static void smbd_idle_event_handler(struct event_context *ctx,
851 struct timed_event *te,
852 struct timeval now,
853 void *private_data)
855 struct idle_event *event =
856 talloc_get_type_abort(private_data, struct idle_event);
858 TALLOC_FREE(event->te);
860 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
861 event->name, event->te));
863 if (!event->handler(&now, event->private_data)) {
864 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
865 event->name, event->te));
866 /* Don't repeat, delete ourselves */
867 TALLOC_FREE(event);
868 return;
871 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
872 event->name, event->te));
874 event->te = event_add_timed(ctx, event,
875 timeval_sum(&now, &event->interval),
876 smbd_idle_event_handler, event);
878 /* We can't do much but fail here. */
879 SMB_ASSERT(event->te != NULL);
882 struct idle_event *event_add_idle(struct event_context *event_ctx,
883 TALLOC_CTX *mem_ctx,
884 struct timeval interval,
885 const char *name,
886 bool (*handler)(const struct timeval *now,
887 void *private_data),
888 void *private_data)
890 struct idle_event *result;
891 struct timeval now = timeval_current();
893 result = TALLOC_P(mem_ctx, struct idle_event);
894 if (result == NULL) {
895 DEBUG(0, ("talloc failed\n"));
896 return NULL;
899 result->interval = interval;
900 result->handler = handler;
901 result->private_data = private_data;
903 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
904 DEBUG(0, ("talloc failed\n"));
905 TALLOC_FREE(result);
906 return NULL;
909 result->te = event_add_timed(event_ctx, result,
910 timeval_sum(&now, &interval),
911 smbd_idle_event_handler, result);
912 if (result->te == NULL) {
913 DEBUG(0, ("event_add_timed failed\n"));
914 TALLOC_FREE(result);
915 return NULL;
918 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
919 return result;
922 static void smbd_sig_term_handler(struct tevent_context *ev,
923 struct tevent_signal *se,
924 int signum,
925 int count,
926 void *siginfo,
927 void *private_data)
929 exit_server_cleanly("termination signal");
932 void smbd_setup_sig_term_handler(void)
934 struct tevent_signal *se;
936 se = tevent_add_signal(smbd_event_context(),
937 smbd_event_context(),
938 SIGTERM, 0,
939 smbd_sig_term_handler,
940 NULL);
941 if (!se) {
942 exit_server("failed to setup SIGTERM handler");
946 static void smbd_sig_hup_handler(struct tevent_context *ev,
947 struct tevent_signal *se,
948 int signum,
949 int count,
950 void *siginfo,
951 void *private_data)
953 struct messaging_context *msg_ctx = talloc_get_type_abort(
954 private_data, struct messaging_context);
955 change_to_root_user();
956 DEBUG(1,("Reloading services after SIGHUP\n"));
957 reload_services(msg_ctx, smbd_server_conn->sock, False);
958 if (am_parent) {
959 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
963 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
964 struct messaging_context *msg_ctx)
966 struct tevent_signal *se;
968 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
969 msg_ctx);
970 if (!se) {
971 exit_server("failed to setup SIGHUP handler");
975 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
977 int timeout;
978 int num_pfds = 0;
979 int ret;
980 bool retry;
982 timeout = SMBD_SELECT_TIMEOUT * 1000;
985 * Are there any timed events waiting ? If so, ensure we don't
986 * select for longer than it would take to wait for them.
989 event_add_to_poll_args(smbd_event_context(), conn,
990 &conn->pfds, &num_pfds, &timeout);
992 /* Process a signal and timed events now... */
993 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
994 return NT_STATUS_RETRY;
998 int sav;
999 START_PROFILE(smbd_idle);
1001 ret = sys_poll(conn->pfds, num_pfds, timeout);
1002 sav = errno;
1004 END_PROFILE(smbd_idle);
1005 errno = sav;
1008 if (ret == -1) {
1009 if (errno == EINTR) {
1010 return NT_STATUS_RETRY;
1012 return map_nt_error_from_unix(errno);
1015 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1016 num_pfds);
1017 if (retry) {
1018 return NT_STATUS_RETRY;
1021 /* Did we timeout ? */
1022 if (ret == 0) {
1023 return NT_STATUS_RETRY;
1026 /* should not be reached */
1027 return NT_STATUS_INTERNAL_ERROR;
1031 * Only allow 5 outstanding trans requests. We're allocating memory, so
1032 * prevent a DoS.
1035 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1037 int count = 0;
1038 for (; list != NULL; list = list->next) {
1040 if (list->mid == mid) {
1041 return NT_STATUS_INVALID_PARAMETER;
1044 count += 1;
1046 if (count > 5) {
1047 return NT_STATUS_INSUFFICIENT_RESOURCES;
1050 return NT_STATUS_OK;
1054 These flags determine some of the permissions required to do an operation
1056 Note that I don't set NEED_WRITE on some write operations because they
1057 are used by some brain-dead clients when printing, and I don't want to
1058 force write permissions on print services.
1060 #define AS_USER (1<<0)
1061 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1062 #define TIME_INIT (1<<2)
1063 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1064 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1065 #define DO_CHDIR (1<<6)
1068 define a list of possible SMB messages and their corresponding
1069 functions. Any message that has a NULL function is unimplemented -
1070 please feel free to contribute implementations!
1072 static const struct smb_message_struct {
1073 const char *name;
1074 void (*fn)(struct smb_request *req);
1075 int flags;
1076 } smb_messages[256] = {
1078 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1079 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1080 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1081 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1082 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1083 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1084 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1085 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1086 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1087 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1088 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1089 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1090 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1091 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1092 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1093 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1094 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1095 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1096 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1097 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1098 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1099 /* 0x15 */ { NULL, NULL, 0 },
1100 /* 0x16 */ { NULL, NULL, 0 },
1101 /* 0x17 */ { NULL, NULL, 0 },
1102 /* 0x18 */ { NULL, NULL, 0 },
1103 /* 0x19 */ { NULL, NULL, 0 },
1104 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1105 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1106 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1107 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1108 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1109 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1110 /* 0x20 */ { "SMBwritec", NULL,0},
1111 /* 0x21 */ { NULL, NULL, 0 },
1112 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1113 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1114 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1115 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1116 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1117 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1118 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1119 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1120 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1121 /* 0x2b */ { "SMBecho",reply_echo,0},
1122 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1123 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1124 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1125 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1126 /* 0x30 */ { NULL, NULL, 0 },
1127 /* 0x31 */ { NULL, NULL, 0 },
1128 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1129 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1130 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1131 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1132 /* 0x36 */ { NULL, NULL, 0 },
1133 /* 0x37 */ { NULL, NULL, 0 },
1134 /* 0x38 */ { NULL, NULL, 0 },
1135 /* 0x39 */ { NULL, NULL, 0 },
1136 /* 0x3a */ { NULL, NULL, 0 },
1137 /* 0x3b */ { NULL, NULL, 0 },
1138 /* 0x3c */ { NULL, NULL, 0 },
1139 /* 0x3d */ { NULL, NULL, 0 },
1140 /* 0x3e */ { NULL, NULL, 0 },
1141 /* 0x3f */ { NULL, NULL, 0 },
1142 /* 0x40 */ { NULL, NULL, 0 },
1143 /* 0x41 */ { NULL, NULL, 0 },
1144 /* 0x42 */ { NULL, NULL, 0 },
1145 /* 0x43 */ { NULL, NULL, 0 },
1146 /* 0x44 */ { NULL, NULL, 0 },
1147 /* 0x45 */ { NULL, NULL, 0 },
1148 /* 0x46 */ { NULL, NULL, 0 },
1149 /* 0x47 */ { NULL, NULL, 0 },
1150 /* 0x48 */ { NULL, NULL, 0 },
1151 /* 0x49 */ { NULL, NULL, 0 },
1152 /* 0x4a */ { NULL, NULL, 0 },
1153 /* 0x4b */ { NULL, NULL, 0 },
1154 /* 0x4c */ { NULL, NULL, 0 },
1155 /* 0x4d */ { NULL, NULL, 0 },
1156 /* 0x4e */ { NULL, NULL, 0 },
1157 /* 0x4f */ { NULL, NULL, 0 },
1158 /* 0x50 */ { NULL, NULL, 0 },
1159 /* 0x51 */ { NULL, NULL, 0 },
1160 /* 0x52 */ { NULL, NULL, 0 },
1161 /* 0x53 */ { NULL, NULL, 0 },
1162 /* 0x54 */ { NULL, NULL, 0 },
1163 /* 0x55 */ { NULL, NULL, 0 },
1164 /* 0x56 */ { NULL, NULL, 0 },
1165 /* 0x57 */ { NULL, NULL, 0 },
1166 /* 0x58 */ { NULL, NULL, 0 },
1167 /* 0x59 */ { NULL, NULL, 0 },
1168 /* 0x5a */ { NULL, NULL, 0 },
1169 /* 0x5b */ { NULL, NULL, 0 },
1170 /* 0x5c */ { NULL, NULL, 0 },
1171 /* 0x5d */ { NULL, NULL, 0 },
1172 /* 0x5e */ { NULL, NULL, 0 },
1173 /* 0x5f */ { NULL, NULL, 0 },
1174 /* 0x60 */ { NULL, NULL, 0 },
1175 /* 0x61 */ { NULL, NULL, 0 },
1176 /* 0x62 */ { NULL, NULL, 0 },
1177 /* 0x63 */ { NULL, NULL, 0 },
1178 /* 0x64 */ { NULL, NULL, 0 },
1179 /* 0x65 */ { NULL, NULL, 0 },
1180 /* 0x66 */ { NULL, NULL, 0 },
1181 /* 0x67 */ { NULL, NULL, 0 },
1182 /* 0x68 */ { NULL, NULL, 0 },
1183 /* 0x69 */ { NULL, NULL, 0 },
1184 /* 0x6a */ { NULL, NULL, 0 },
1185 /* 0x6b */ { NULL, NULL, 0 },
1186 /* 0x6c */ { NULL, NULL, 0 },
1187 /* 0x6d */ { NULL, NULL, 0 },
1188 /* 0x6e */ { NULL, NULL, 0 },
1189 /* 0x6f */ { NULL, NULL, 0 },
1190 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1191 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1192 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1193 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1194 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1195 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1196 /* 0x76 */ { NULL, NULL, 0 },
1197 /* 0x77 */ { NULL, NULL, 0 },
1198 /* 0x78 */ { NULL, NULL, 0 },
1199 /* 0x79 */ { NULL, NULL, 0 },
1200 /* 0x7a */ { NULL, NULL, 0 },
1201 /* 0x7b */ { NULL, NULL, 0 },
1202 /* 0x7c */ { NULL, NULL, 0 },
1203 /* 0x7d */ { NULL, NULL, 0 },
1204 /* 0x7e */ { NULL, NULL, 0 },
1205 /* 0x7f */ { NULL, NULL, 0 },
1206 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1207 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1208 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1209 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1210 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1211 /* 0x85 */ { NULL, NULL, 0 },
1212 /* 0x86 */ { NULL, NULL, 0 },
1213 /* 0x87 */ { NULL, NULL, 0 },
1214 /* 0x88 */ { NULL, NULL, 0 },
1215 /* 0x89 */ { NULL, NULL, 0 },
1216 /* 0x8a */ { NULL, NULL, 0 },
1217 /* 0x8b */ { NULL, NULL, 0 },
1218 /* 0x8c */ { NULL, NULL, 0 },
1219 /* 0x8d */ { NULL, NULL, 0 },
1220 /* 0x8e */ { NULL, NULL, 0 },
1221 /* 0x8f */ { NULL, NULL, 0 },
1222 /* 0x90 */ { NULL, NULL, 0 },
1223 /* 0x91 */ { NULL, NULL, 0 },
1224 /* 0x92 */ { NULL, NULL, 0 },
1225 /* 0x93 */ { NULL, NULL, 0 },
1226 /* 0x94 */ { NULL, NULL, 0 },
1227 /* 0x95 */ { NULL, NULL, 0 },
1228 /* 0x96 */ { NULL, NULL, 0 },
1229 /* 0x97 */ { NULL, NULL, 0 },
1230 /* 0x98 */ { NULL, NULL, 0 },
1231 /* 0x99 */ { NULL, NULL, 0 },
1232 /* 0x9a */ { NULL, NULL, 0 },
1233 /* 0x9b */ { NULL, NULL, 0 },
1234 /* 0x9c */ { NULL, NULL, 0 },
1235 /* 0x9d */ { NULL, NULL, 0 },
1236 /* 0x9e */ { NULL, NULL, 0 },
1237 /* 0x9f */ { NULL, NULL, 0 },
1238 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1239 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1240 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1241 /* 0xa3 */ { NULL, NULL, 0 },
1242 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1243 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1244 /* 0xa6 */ { NULL, NULL, 0 },
1245 /* 0xa7 */ { NULL, NULL, 0 },
1246 /* 0xa8 */ { NULL, NULL, 0 },
1247 /* 0xa9 */ { NULL, NULL, 0 },
1248 /* 0xaa */ { NULL, NULL, 0 },
1249 /* 0xab */ { NULL, NULL, 0 },
1250 /* 0xac */ { NULL, NULL, 0 },
1251 /* 0xad */ { NULL, NULL, 0 },
1252 /* 0xae */ { NULL, NULL, 0 },
1253 /* 0xaf */ { NULL, NULL, 0 },
1254 /* 0xb0 */ { NULL, NULL, 0 },
1255 /* 0xb1 */ { NULL, NULL, 0 },
1256 /* 0xb2 */ { NULL, NULL, 0 },
1257 /* 0xb3 */ { NULL, NULL, 0 },
1258 /* 0xb4 */ { NULL, NULL, 0 },
1259 /* 0xb5 */ { NULL, NULL, 0 },
1260 /* 0xb6 */ { NULL, NULL, 0 },
1261 /* 0xb7 */ { NULL, NULL, 0 },
1262 /* 0xb8 */ { NULL, NULL, 0 },
1263 /* 0xb9 */ { NULL, NULL, 0 },
1264 /* 0xba */ { NULL, NULL, 0 },
1265 /* 0xbb */ { NULL, NULL, 0 },
1266 /* 0xbc */ { NULL, NULL, 0 },
1267 /* 0xbd */ { NULL, NULL, 0 },
1268 /* 0xbe */ { NULL, NULL, 0 },
1269 /* 0xbf */ { NULL, NULL, 0 },
1270 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1271 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1272 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1273 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1274 /* 0xc4 */ { NULL, NULL, 0 },
1275 /* 0xc5 */ { NULL, NULL, 0 },
1276 /* 0xc6 */ { NULL, NULL, 0 },
1277 /* 0xc7 */ { NULL, NULL, 0 },
1278 /* 0xc8 */ { NULL, NULL, 0 },
1279 /* 0xc9 */ { NULL, NULL, 0 },
1280 /* 0xca */ { NULL, NULL, 0 },
1281 /* 0xcb */ { NULL, NULL, 0 },
1282 /* 0xcc */ { NULL, NULL, 0 },
1283 /* 0xcd */ { NULL, NULL, 0 },
1284 /* 0xce */ { NULL, NULL, 0 },
1285 /* 0xcf */ { NULL, NULL, 0 },
1286 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1287 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1288 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1289 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1290 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1291 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1292 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1293 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1294 /* 0xd8 */ { NULL, NULL, 0 },
1295 /* 0xd9 */ { NULL, NULL, 0 },
1296 /* 0xda */ { NULL, NULL, 0 },
1297 /* 0xdb */ { NULL, NULL, 0 },
1298 /* 0xdc */ { NULL, NULL, 0 },
1299 /* 0xdd */ { NULL, NULL, 0 },
1300 /* 0xde */ { NULL, NULL, 0 },
1301 /* 0xdf */ { NULL, NULL, 0 },
1302 /* 0xe0 */ { NULL, NULL, 0 },
1303 /* 0xe1 */ { NULL, NULL, 0 },
1304 /* 0xe2 */ { NULL, NULL, 0 },
1305 /* 0xe3 */ { NULL, NULL, 0 },
1306 /* 0xe4 */ { NULL, NULL, 0 },
1307 /* 0xe5 */ { NULL, NULL, 0 },
1308 /* 0xe6 */ { NULL, NULL, 0 },
1309 /* 0xe7 */ { NULL, NULL, 0 },
1310 /* 0xe8 */ { NULL, NULL, 0 },
1311 /* 0xe9 */ { NULL, NULL, 0 },
1312 /* 0xea */ { NULL, NULL, 0 },
1313 /* 0xeb */ { NULL, NULL, 0 },
1314 /* 0xec */ { NULL, NULL, 0 },
1315 /* 0xed */ { NULL, NULL, 0 },
1316 /* 0xee */ { NULL, NULL, 0 },
1317 /* 0xef */ { NULL, NULL, 0 },
1318 /* 0xf0 */ { NULL, NULL, 0 },
1319 /* 0xf1 */ { NULL, NULL, 0 },
1320 /* 0xf2 */ { NULL, NULL, 0 },
1321 /* 0xf3 */ { NULL, NULL, 0 },
1322 /* 0xf4 */ { NULL, NULL, 0 },
1323 /* 0xf5 */ { NULL, NULL, 0 },
1324 /* 0xf6 */ { NULL, NULL, 0 },
1325 /* 0xf7 */ { NULL, NULL, 0 },
1326 /* 0xf8 */ { NULL, NULL, 0 },
1327 /* 0xf9 */ { NULL, NULL, 0 },
1328 /* 0xfa */ { NULL, NULL, 0 },
1329 /* 0xfb */ { NULL, NULL, 0 },
1330 /* 0xfc */ { NULL, NULL, 0 },
1331 /* 0xfd */ { NULL, NULL, 0 },
1332 /* 0xfe */ { NULL, NULL, 0 },
1333 /* 0xff */ { NULL, NULL, 0 }
1337 /*******************************************************************
1338 allocate and initialize a reply packet
1339 ********************************************************************/
1341 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1342 const char *inbuf, char **outbuf, uint8_t num_words,
1343 uint32_t num_bytes)
1346 * Protect against integer wrap
1348 if ((num_bytes > 0xffffff)
1349 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1350 char *msg;
1351 if (asprintf(&msg, "num_bytes too large: %u",
1352 (unsigned)num_bytes) == -1) {
1353 msg = CONST_DISCARD(char *, "num_bytes too large");
1355 smb_panic(msg);
1358 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1359 smb_size + num_words*2 + num_bytes);
1360 if (*outbuf == NULL) {
1361 return false;
1364 construct_reply_common(req, inbuf, *outbuf);
1365 srv_set_message(*outbuf, num_words, num_bytes, false);
1367 * Zero out the word area, the caller has to take care of the bcc area
1368 * himself
1370 if (num_words != 0) {
1371 memset(*outbuf + smb_vwv0, 0, num_words*2);
1374 return true;
1377 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1379 char *outbuf;
1380 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1381 num_bytes)) {
1382 smb_panic("could not allocate output buffer\n");
1384 req->outbuf = (uint8_t *)outbuf;
1388 /*******************************************************************
1389 Dump a packet to a file.
1390 ********************************************************************/
1392 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1394 int fd, i;
1395 char *fname = NULL;
1396 if (DEBUGLEVEL < 50) {
1397 return;
1400 if (len < 4) len = smb_len(data)+4;
1401 for (i=1;i<100;i++) {
1402 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1403 type ? "req" : "resp") == -1) {
1404 return;
1406 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1407 if (fd != -1 || errno != EEXIST) break;
1409 if (fd != -1) {
1410 ssize_t ret = write(fd, data, len);
1411 if (ret != len)
1412 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1413 close(fd);
1414 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1416 SAFE_FREE(fname);
1419 /****************************************************************************
1420 Prepare everything for calling the actual request function, and potentially
1421 call the request function via the "new" interface.
1423 Return False if the "legacy" function needs to be called, everything is
1424 prepared.
1426 Return True if we're done.
1428 I know this API sucks, but it is the one with the least code change I could
1429 find.
1430 ****************************************************************************/
1432 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1434 int flags;
1435 uint16 session_tag;
1436 connection_struct *conn = NULL;
1437 struct smbd_server_connection *sconn = req->sconn;
1439 errno = 0;
1441 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1442 * so subtract 4 from it. */
1443 if (!valid_smb_header(req->inbuf)
1444 || (size < (smb_size - 4))) {
1445 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1446 smb_len(req->inbuf)));
1447 exit_server_cleanly("Non-SMB packet");
1450 if (smb_messages[type].fn == NULL) {
1451 DEBUG(0,("Unknown message type %d!\n",type));
1452 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1453 reply_unknown_new(req, type);
1454 return NULL;
1457 flags = smb_messages[type].flags;
1459 /* In share mode security we must ignore the vuid. */
1460 session_tag = (lp_security() == SEC_SHARE)
1461 ? UID_FIELD_INVALID : req->vuid;
1462 conn = req->conn;
1464 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1465 (int)sys_getpid(), (unsigned long)conn));
1467 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1469 /* Ensure this value is replaced in the incoming packet. */
1470 SSVAL(req->inbuf,smb_uid,session_tag);
1473 * Ensure the correct username is in current_user_info. This is a
1474 * really ugly bugfix for problems with multiple session_setup_and_X's
1475 * being done and allowing %U and %G substitutions to work correctly.
1476 * There is a reason this code is done here, don't move it unless you
1477 * know what you're doing... :-).
1478 * JRA.
1481 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1482 user_struct *vuser = NULL;
1484 sconn->smb1.sessions.last_session_tag = session_tag;
1485 if(session_tag != UID_FIELD_INVALID) {
1486 vuser = get_valid_user_struct(sconn, session_tag);
1487 if (vuser) {
1488 set_current_user_info(
1489 vuser->session_info->sanitized_username,
1490 vuser->session_info->unix_name,
1491 vuser->session_info->info3->base.domain.string);
1496 /* Does this call need to be run as the connected user? */
1497 if (flags & AS_USER) {
1499 /* Does this call need a valid tree connection? */
1500 if (!conn) {
1502 * Amazingly, the error code depends on the command
1503 * (from Samba4).
1505 if (type == SMBntcreateX) {
1506 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1507 } else {
1508 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1510 return NULL;
1513 if (!change_to_user(conn,session_tag)) {
1514 DEBUG(0, ("Error: Could not change to user. Removing "
1515 "deferred open, mid=%llu.\n",
1516 (unsigned long long)req->mid));
1517 reply_force_doserror(req, ERRSRV, ERRbaduid);
1518 return conn;
1521 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1523 /* Does it need write permission? */
1524 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1525 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1526 return conn;
1529 /* IPC services are limited */
1530 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1531 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 return conn;
1534 } else {
1535 /* This call needs to be run as root */
1536 change_to_root_user();
1539 /* load service specific parameters */
1540 if (conn) {
1541 if (req->encrypted) {
1542 conn->encrypted_tid = true;
1543 /* encrypted required from now on. */
1544 conn->encrypt_level = Required;
1545 } else if (ENCRYPTION_REQUIRED(conn)) {
1546 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1547 exit_server_cleanly("encryption required "
1548 "on connection");
1549 return conn;
1553 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1554 (flags & (AS_USER|DO_CHDIR)
1555 ?True:False))) {
1556 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1557 return conn;
1559 conn->num_smb_operations++;
1562 /* does this protocol need to be run as guest? */
1563 if ((flags & AS_GUEST)
1564 && (!change_to_guest() ||
1565 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1566 sconn->client_id.name,
1567 sconn->client_id.addr))) {
1568 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1569 return conn;
1572 smb_messages[type].fn(req);
1573 return req->conn;
1576 /****************************************************************************
1577 Construct a reply to the incoming packet.
1578 ****************************************************************************/
1580 static void construct_reply(struct smbd_server_connection *sconn,
1581 char *inbuf, int size, size_t unread_bytes,
1582 uint32_t seqnum, bool encrypted,
1583 struct smb_perfcount_data *deferred_pcd)
1585 connection_struct *conn;
1586 struct smb_request *req;
1588 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1589 smb_panic("could not allocate smb_request");
1592 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1593 encrypted, seqnum)) {
1594 exit_server_cleanly("Invalid SMB request");
1597 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1599 /* we popped this message off the queue - keep original perf data */
1600 if (deferred_pcd)
1601 req->pcd = *deferred_pcd;
1602 else {
1603 SMB_PERFCOUNT_START(&req->pcd);
1604 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1605 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1608 conn = switch_message(req->cmd, req, size);
1610 if (req->unread_bytes) {
1611 /* writeX failed. drain socket. */
1612 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1613 req->unread_bytes) {
1614 smb_panic("failed to drain pending bytes");
1616 req->unread_bytes = 0;
1619 if (req->done) {
1620 TALLOC_FREE(req);
1621 return;
1624 if (req->outbuf == NULL) {
1625 return;
1628 if (CVAL(req->outbuf,0) == 0) {
1629 show_msg((char *)req->outbuf);
1632 if (!srv_send_smb(req->sconn,
1633 (char *)req->outbuf,
1634 true, req->seqnum+1,
1635 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1636 &req->pcd)) {
1637 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1640 TALLOC_FREE(req);
1642 return;
1645 /****************************************************************************
1646 Process an smb from the client
1647 ****************************************************************************/
1648 static void process_smb(struct smbd_server_connection *sconn,
1649 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1650 uint32_t seqnum, bool encrypted,
1651 struct smb_perfcount_data *deferred_pcd)
1653 int msg_type = CVAL(inbuf,0);
1655 DO_PROFILE_INC(smb_count);
1657 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1658 smb_len(inbuf) ) );
1659 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1660 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1662 if (msg_type != 0) {
1664 * NetBIOS session request, keepalive, etc.
1666 reply_special(sconn, (char *)inbuf, nread);
1667 goto done;
1670 if (sconn->using_smb2) {
1671 /* At this point we're not really using smb2,
1672 * we make the decision here.. */
1673 if (smbd_is_smb2_header(inbuf, nread)) {
1674 smbd_smb2_first_negprot(sconn, inbuf, nread);
1675 return;
1676 } else if (nread >= smb_size && valid_smb_header(inbuf)
1677 && CVAL(inbuf, smb_com) != 0x72) {
1678 /* This is a non-negprot SMB1 packet.
1679 Disable SMB2 from now on. */
1680 sconn->using_smb2 = false;
1684 show_msg((char *)inbuf);
1686 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1687 encrypted, deferred_pcd);
1688 sconn->trans_num++;
1690 done:
1691 sconn->smb1.num_requests++;
1693 /* The timeout_processing function isn't run nearly
1694 often enough to implement 'max log size' without
1695 overrunning the size of the file by many megabytes.
1696 This is especially true if we are running at debug
1697 level 10. Checking every 50 SMBs is a nice
1698 tradeoff of performance vs log file size overrun. */
1700 if ((sconn->smb1.num_requests % 50) == 0 &&
1701 need_to_check_log_size()) {
1702 change_to_root_user();
1703 check_log_size();
1707 /****************************************************************************
1708 Return a string containing the function name of a SMB command.
1709 ****************************************************************************/
1711 const char *smb_fn_name(int type)
1713 const char *unknown_name = "SMBunknown";
1715 if (smb_messages[type].name == NULL)
1716 return(unknown_name);
1718 return(smb_messages[type].name);
1721 /****************************************************************************
1722 Helper functions for contruct_reply.
1723 ****************************************************************************/
1725 void add_to_common_flags2(uint32 v)
1727 common_flags2 |= v;
1730 void remove_from_common_flags2(uint32 v)
1732 common_flags2 &= ~v;
1735 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1736 char *outbuf)
1738 srv_set_message(outbuf,0,0,false);
1740 SCVAL(outbuf, smb_com, req->cmd);
1741 SIVAL(outbuf,smb_rcls,0);
1742 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1743 SSVAL(outbuf,smb_flg2,
1744 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1745 common_flags2);
1746 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1748 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1749 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1750 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1751 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1754 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1756 construct_reply_common(req, (char *)req->inbuf, outbuf);
1760 * How many bytes have we already accumulated up to the current wct field
1761 * offset?
1764 size_t req_wct_ofs(struct smb_request *req)
1766 size_t buf_size;
1768 if (req->chain_outbuf == NULL) {
1769 return smb_wct - 4;
1771 buf_size = talloc_get_size(req->chain_outbuf);
1772 if ((buf_size % 4) != 0) {
1773 buf_size += (4 - (buf_size % 4));
1775 return buf_size - 4;
1779 * Hack around reply_nterror & friends not being aware of chained requests,
1780 * generating illegal (i.e. wct==0) chain replies.
1783 static void fixup_chain_error_packet(struct smb_request *req)
1785 uint8_t *outbuf = req->outbuf;
1786 req->outbuf = NULL;
1787 reply_outbuf(req, 2, 0);
1788 memcpy(req->outbuf, outbuf, smb_wct);
1789 TALLOC_FREE(outbuf);
1790 SCVAL(req->outbuf, smb_vwv0, 0xff);
1794 * @brief Find the smb_cmd offset of the last command pushed
1795 * @param[in] buf The buffer we're building up
1796 * @retval Where can we put our next andx cmd?
1798 * While chaining requests, the "next" request we're looking at needs to put
1799 * its SMB_Command before the data the previous request already built up added
1800 * to the chain. Find the offset to the place where we have to put our cmd.
1803 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1805 uint8_t cmd;
1806 size_t ofs;
1808 cmd = CVAL(buf, smb_com);
1810 SMB_ASSERT(is_andx_req(cmd));
1812 ofs = smb_vwv0;
1814 while (CVAL(buf, ofs) != 0xff) {
1816 if (!is_andx_req(CVAL(buf, ofs))) {
1817 return false;
1821 * ofs is from start of smb header, so add the 4 length
1822 * bytes. The next cmd is right after the wct field.
1824 ofs = SVAL(buf, ofs+2) + 4 + 1;
1826 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1829 *pofs = ofs;
1830 return true;
1834 * @brief Do the smb chaining at a buffer level
1835 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1836 * @param[in] smb_command The command that we want to issue
1837 * @param[in] wct How many words?
1838 * @param[in] vwv The words, already in network order
1839 * @param[in] bytes_alignment How shall we align "bytes"?
1840 * @param[in] num_bytes How many bytes?
1841 * @param[in] bytes The data the request ships
1843 * smb_splice_chain() adds the vwv and bytes to the request already present in
1844 * *poutbuf.
1847 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1848 uint8_t wct, const uint16_t *vwv,
1849 size_t bytes_alignment,
1850 uint32_t num_bytes, const uint8_t *bytes)
1852 uint8_t *outbuf;
1853 size_t old_size, new_size;
1854 size_t ofs;
1855 size_t chain_padding = 0;
1856 size_t bytes_padding = 0;
1857 bool first_request;
1859 old_size = talloc_get_size(*poutbuf);
1862 * old_size == smb_wct means we're pushing the first request in for
1863 * libsmb/
1866 first_request = (old_size == smb_wct);
1868 if (!first_request && ((old_size % 4) != 0)) {
1870 * Align the wct field of subsequent requests to a 4-byte
1871 * boundary
1873 chain_padding = 4 - (old_size % 4);
1877 * After the old request comes the new wct field (1 byte), the vwv's
1878 * and the num_bytes field. After at we might need to align the bytes
1879 * given to us to "bytes_alignment", increasing the num_bytes value.
1882 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1884 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1885 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1888 new_size += bytes_padding + num_bytes;
1890 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1891 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1892 (unsigned)new_size));
1893 return false;
1896 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1897 if (outbuf == NULL) {
1898 DEBUG(0, ("talloc failed\n"));
1899 return false;
1901 *poutbuf = outbuf;
1903 if (first_request) {
1904 SCVAL(outbuf, smb_com, smb_command);
1905 } else {
1906 size_t andx_cmd_ofs;
1908 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1909 DEBUG(1, ("invalid command chain\n"));
1910 *poutbuf = TALLOC_REALLOC_ARRAY(
1911 NULL, *poutbuf, uint8_t, old_size);
1912 return false;
1915 if (chain_padding != 0) {
1916 memset(outbuf + old_size, 0, chain_padding);
1917 old_size += chain_padding;
1920 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1921 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1924 ofs = old_size;
1927 * Push the chained request:
1929 * wct field
1932 SCVAL(outbuf, ofs, wct);
1933 ofs += 1;
1936 * vwv array
1939 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1940 ofs += sizeof(uint16_t) * wct;
1943 * bcc (byte count)
1946 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1947 ofs += sizeof(uint16_t);
1950 * padding
1953 if (bytes_padding != 0) {
1954 memset(outbuf + ofs, 0, bytes_padding);
1955 ofs += bytes_padding;
1959 * The bytes field
1962 memcpy(outbuf + ofs, bytes, num_bytes);
1964 return true;
1967 /****************************************************************************
1968 Construct a chained reply and add it to the already made reply
1969 ****************************************************************************/
1971 void chain_reply(struct smb_request *req)
1973 size_t smblen = smb_len(req->inbuf);
1974 size_t already_used, length_needed;
1975 uint8_t chain_cmd;
1976 uint32_t chain_offset; /* uint32_t to avoid overflow */
1978 uint8_t wct;
1979 uint16_t *vwv;
1980 uint16_t buflen;
1981 uint8_t *buf;
1983 if (IVAL(req->outbuf, smb_rcls) != 0) {
1984 fixup_chain_error_packet(req);
1988 * Any of the AndX requests and replies have at least a wct of
1989 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1990 * beginning of the SMB header to the next wct field.
1992 * None of the AndX requests put anything valuable in vwv[0] and [1],
1993 * so we can overwrite it here to form the chain.
1996 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1997 if (req->chain_outbuf == NULL) {
1998 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1999 req, req->outbuf, uint8_t,
2000 smb_len(req->outbuf) + 4);
2001 if (req->chain_outbuf == NULL) {
2002 smb_panic("talloc failed");
2005 req->outbuf = NULL;
2006 goto error;
2010 * Here we assume that this is the end of the chain. For that we need
2011 * to set "next command" to 0xff and the offset to 0. If we later find
2012 * more commands in the chain, this will be overwritten again.
2015 SCVAL(req->outbuf, smb_vwv0, 0xff);
2016 SCVAL(req->outbuf, smb_vwv0+1, 0);
2017 SSVAL(req->outbuf, smb_vwv1, 0);
2019 if (req->chain_outbuf == NULL) {
2021 * In req->chain_outbuf we collect all the replies. Start the
2022 * chain by copying in the first reply.
2024 * We do the realloc because later on we depend on
2025 * talloc_get_size to determine the length of
2026 * chain_outbuf. The reply_xxx routines might have
2027 * over-allocated (reply_pipe_read_and_X used to be such an
2028 * example).
2030 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2031 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2032 if (req->chain_outbuf == NULL) {
2033 smb_panic("talloc failed");
2035 req->outbuf = NULL;
2036 } else {
2038 * Update smb headers where subsequent chained commands
2039 * may have updated them.
2041 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2042 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2044 if (!smb_splice_chain(&req->chain_outbuf,
2045 CVAL(req->outbuf, smb_com),
2046 CVAL(req->outbuf, smb_wct),
2047 (uint16_t *)(req->outbuf + smb_vwv),
2048 0, smb_buflen(req->outbuf),
2049 (uint8_t *)smb_buf(req->outbuf))) {
2050 goto error;
2052 TALLOC_FREE(req->outbuf);
2056 * We use the old request's vwv field to grab the next chained command
2057 * and offset into the chained fields.
2060 chain_cmd = CVAL(req->vwv+0, 0);
2061 chain_offset = SVAL(req->vwv+1, 0);
2063 if (chain_cmd == 0xff) {
2065 * End of chain, no more requests from the client. So ship the
2066 * replies.
2068 smb_setlen((char *)(req->chain_outbuf),
2069 talloc_get_size(req->chain_outbuf) - 4);
2071 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2072 true, req->seqnum+1,
2073 IS_CONN_ENCRYPTED(req->conn)
2074 ||req->encrypted,
2075 &req->pcd)) {
2076 exit_server_cleanly("chain_reply: srv_send_smb "
2077 "failed.");
2079 TALLOC_FREE(req->chain_outbuf);
2080 req->done = true;
2081 return;
2084 /* add a new perfcounter for this element of chain */
2085 SMB_PERFCOUNT_ADD(&req->pcd);
2086 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2087 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2090 * Check if the client tries to fool us. The request so far uses the
2091 * space to the end of the byte buffer in the request just
2092 * processed. The chain_offset can't point into that area. If that was
2093 * the case, we could end up with an endless processing of the chain,
2094 * we would always handle the same request.
2097 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2098 if (chain_offset < already_used) {
2099 goto error;
2103 * Next check: Make sure the chain offset does not point beyond the
2104 * overall smb request length.
2107 length_needed = chain_offset+1; /* wct */
2108 if (length_needed > smblen) {
2109 goto error;
2113 * Now comes the pointer magic. Goal here is to set up req->vwv and
2114 * req->buf correctly again to be able to call the subsequent
2115 * switch_message(). The chain offset (the former vwv[1]) points at
2116 * the new wct field.
2119 wct = CVAL(smb_base(req->inbuf), chain_offset);
2122 * Next consistency check: Make the new vwv array fits in the overall
2123 * smb request.
2126 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2127 if (length_needed > smblen) {
2128 goto error;
2130 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2133 * Now grab the new byte buffer....
2136 buflen = SVAL(vwv+wct, 0);
2139 * .. and check that it fits.
2142 length_needed += buflen;
2143 if (length_needed > smblen) {
2144 goto error;
2146 buf = (uint8_t *)(vwv+wct+1);
2148 req->cmd = chain_cmd;
2149 req->wct = wct;
2150 req->vwv = vwv;
2151 req->buflen = buflen;
2152 req->buf = buf;
2154 switch_message(chain_cmd, req, smblen);
2156 if (req->outbuf == NULL) {
2158 * This happens if the chained command has suspended itself or
2159 * if it has called srv_send_smb() itself.
2161 return;
2165 * We end up here if the chained command was not itself chained or
2166 * suspended, but for example a close() command. We now need to splice
2167 * the chained commands' outbuf into the already built up chain_outbuf
2168 * and ship the result.
2170 goto done;
2172 error:
2174 * We end up here if there's any error in the chain syntax. Report a
2175 * DOS error, just like Windows does.
2177 reply_force_doserror(req, ERRSRV, ERRerror);
2178 fixup_chain_error_packet(req);
2180 done:
2182 * This scary statement intends to set the
2183 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2184 * to the value req->outbuf carries
2186 SSVAL(req->chain_outbuf, smb_flg2,
2187 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2188 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2191 * Transfer the error codes from the subrequest to the main one
2193 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2194 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2196 if (!smb_splice_chain(&req->chain_outbuf,
2197 CVAL(req->outbuf, smb_com),
2198 CVAL(req->outbuf, smb_wct),
2199 (uint16_t *)(req->outbuf + smb_vwv),
2200 0, smb_buflen(req->outbuf),
2201 (uint8_t *)smb_buf(req->outbuf))) {
2202 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2204 TALLOC_FREE(req->outbuf);
2206 smb_setlen((char *)(req->chain_outbuf),
2207 talloc_get_size(req->chain_outbuf) - 4);
2209 show_msg((char *)(req->chain_outbuf));
2211 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2212 true, req->seqnum+1,
2213 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2214 &req->pcd)) {
2215 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2217 TALLOC_FREE(req->chain_outbuf);
2218 req->done = true;
2221 /****************************************************************************
2222 Check if services need reloading.
2223 ****************************************************************************/
2225 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2228 if (last_smb_conf_reload_time == 0) {
2229 last_smb_conf_reload_time = t;
2232 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2233 reload_services(sconn->msg_ctx, sconn->sock, True);
2234 last_smb_conf_reload_time = t;
2238 static bool fd_is_readable(int fd)
2240 int ret, revents;
2242 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2244 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2248 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2250 /* TODO: make write nonblocking */
2253 static void smbd_server_connection_read_handler(
2254 struct smbd_server_connection *conn, int fd)
2256 uint8_t *inbuf = NULL;
2257 size_t inbuf_len = 0;
2258 size_t unread_bytes = 0;
2259 bool encrypted = false;
2260 TALLOC_CTX *mem_ctx = talloc_tos();
2261 NTSTATUS status;
2262 uint32_t seqnum;
2264 bool from_client = (conn->sock == fd);
2266 if (from_client) {
2267 smbd_lock_socket(conn);
2269 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2270 DEBUG(10,("the echo listener was faster\n"));
2271 smbd_unlock_socket(conn);
2272 return;
2275 /* TODO: make this completely nonblocking */
2276 status = receive_smb_talloc(mem_ctx, conn, fd,
2277 (char **)(void *)&inbuf,
2278 0, /* timeout */
2279 &unread_bytes,
2280 &encrypted,
2281 &inbuf_len, &seqnum,
2282 false /* trusted channel */);
2283 smbd_unlock_socket(conn);
2284 } else {
2285 /* TODO: make this completely nonblocking */
2286 status = receive_smb_talloc(mem_ctx, conn, fd,
2287 (char **)(void *)&inbuf,
2288 0, /* timeout */
2289 &unread_bytes,
2290 &encrypted,
2291 &inbuf_len, &seqnum,
2292 true /* trusted channel */);
2295 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2296 goto process;
2298 if (NT_STATUS_IS_ERR(status)) {
2299 exit_server_cleanly("failed to receive smb request");
2301 if (!NT_STATUS_IS_OK(status)) {
2302 return;
2305 process:
2306 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2307 seqnum, encrypted, NULL);
2310 static void smbd_server_connection_handler(struct event_context *ev,
2311 struct fd_event *fde,
2312 uint16_t flags,
2313 void *private_data)
2315 struct smbd_server_connection *conn = talloc_get_type(private_data,
2316 struct smbd_server_connection);
2318 if (flags & EVENT_FD_WRITE) {
2319 smbd_server_connection_write_handler(conn);
2320 return;
2322 if (flags & EVENT_FD_READ) {
2323 smbd_server_connection_read_handler(conn, conn->sock);
2324 return;
2328 static void smbd_server_echo_handler(struct event_context *ev,
2329 struct fd_event *fde,
2330 uint16_t flags,
2331 void *private_data)
2333 struct smbd_server_connection *conn = talloc_get_type(private_data,
2334 struct smbd_server_connection);
2336 if (flags & EVENT_FD_WRITE) {
2337 smbd_server_connection_write_handler(conn);
2338 return;
2340 if (flags & EVENT_FD_READ) {
2341 smbd_server_connection_read_handler(
2342 conn, conn->smb1.echo_handler.trusted_fd);
2343 return;
2347 /****************************************************************************
2348 received when we should release a specific IP
2349 ****************************************************************************/
2350 static void release_ip(const char *ip, void *priv)
2352 const char *addr = (const char *)priv;
2353 const char *p = addr;
2355 if (strncmp("::ffff:", addr, 7) == 0) {
2356 p = addr + 7;
2359 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2360 /* we can't afford to do a clean exit - that involves
2361 database writes, which would potentially mean we
2362 are still running after the failover has finished -
2363 we have to get rid of this process ID straight
2364 away */
2365 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2366 ip));
2367 /* note we must exit with non-zero status so the unclean handler gets
2368 called in the parent, so that the brl database is tickled */
2369 _exit(1);
2373 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2374 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2376 struct smbd_server_connection *sconn = talloc_get_type_abort(
2377 private_data, struct smbd_server_connection);
2379 release_ip((char *)data->data, sconn->client_id.addr);
2382 #ifdef CLUSTER_SUPPORT
2383 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2384 struct sockaddr_storage *client)
2386 socklen_t length;
2387 length = sizeof(*server);
2388 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2389 return -1;
2391 length = sizeof(*client);
2392 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2393 return -1;
2395 return 0;
2397 #endif
2400 * Send keepalive packets to our client
2402 static bool keepalive_fn(const struct timeval *now, void *private_data)
2404 struct smbd_server_connection *sconn = smbd_server_conn;
2405 bool ret;
2407 if (sconn->using_smb2) {
2408 /* Don't do keepalives on an SMB2 connection. */
2409 return false;
2412 smbd_lock_socket(smbd_server_conn);
2413 ret = send_keepalive(sconn->sock);
2414 smbd_unlock_socket(smbd_server_conn);
2416 if (!ret) {
2417 char addr[INET6_ADDRSTRLEN];
2419 * Try and give an error message saying what
2420 * client failed.
2422 DEBUG(0, ("send_keepalive failed for client %s. "
2423 "Error %s - exiting\n",
2424 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2425 strerror(errno)));
2426 return False;
2428 return True;
2432 * Do the recurring check if we're idle
2434 static bool deadtime_fn(const struct timeval *now, void *private_data)
2436 struct smbd_server_connection *sconn =
2437 (struct smbd_server_connection *)private_data;
2439 if ((conn_num_open(sconn) == 0)
2440 || (conn_idle_all(sconn, now->tv_sec))) {
2441 DEBUG( 2, ( "Closing idle connection\n" ) );
2442 messaging_send(sconn->msg_ctx,
2443 messaging_server_id(sconn->msg_ctx),
2444 MSG_SHUTDOWN, &data_blob_null);
2445 return False;
2448 return True;
2452 * Do the recurring log file and smb.conf reload checks.
2455 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2457 struct smbd_server_connection *sconn = talloc_get_type_abort(
2458 private_data, struct smbd_server_connection);
2460 DEBUG(5, ("housekeeping\n"));
2462 change_to_root_user();
2464 /* update printer queue caches if necessary */
2465 update_monitored_printq_cache(sconn->msg_ctx);
2467 /* check if we need to reload services */
2468 check_reload(sconn, time_mono(NULL));
2470 /* Change machine password if neccessary. */
2471 attempt_machine_password_change();
2474 * Force a log file check.
2476 force_check_log_size();
2477 check_log_size();
2478 return true;
2481 static int create_unlink_tmp(const char *dir)
2483 char *fname;
2484 int fd;
2486 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2487 if (fname == NULL) {
2488 errno = ENOMEM;
2489 return -1;
2491 fd = mkstemp(fname);
2492 if (fd == -1) {
2493 TALLOC_FREE(fname);
2494 return -1;
2496 if (unlink(fname) == -1) {
2497 int sys_errno = errno;
2498 close(fd);
2499 TALLOC_FREE(fname);
2500 errno = sys_errno;
2501 return -1;
2503 TALLOC_FREE(fname);
2504 return fd;
2507 struct smbd_echo_state {
2508 struct tevent_context *ev;
2509 struct iovec *pending;
2510 struct smbd_server_connection *sconn;
2511 int parent_pipe;
2513 struct tevent_fd *parent_fde;
2515 struct tevent_fd *read_fde;
2516 struct tevent_req *write_req;
2519 static void smbd_echo_writer_done(struct tevent_req *req);
2521 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2523 int num_pending;
2525 if (state->write_req != NULL) {
2526 return;
2529 num_pending = talloc_array_length(state->pending);
2530 if (num_pending == 0) {
2531 return;
2534 state->write_req = writev_send(state, state->ev, NULL,
2535 state->parent_pipe, false,
2536 state->pending, num_pending);
2537 if (state->write_req == NULL) {
2538 DEBUG(1, ("writev_send failed\n"));
2539 exit(1);
2542 talloc_steal(state->write_req, state->pending);
2543 state->pending = NULL;
2545 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2546 state);
2549 static void smbd_echo_writer_done(struct tevent_req *req)
2551 struct smbd_echo_state *state = tevent_req_callback_data(
2552 req, struct smbd_echo_state);
2553 ssize_t written;
2554 int err;
2556 written = writev_recv(req, &err);
2557 TALLOC_FREE(req);
2558 state->write_req = NULL;
2559 if (written == -1) {
2560 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2561 exit(1);
2563 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2564 smbd_echo_activate_writer(state);
2567 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2568 uint32_t seqnum)
2570 struct smb_request req;
2571 uint16_t num_replies;
2572 size_t out_len;
2573 char *outbuf;
2574 bool ok;
2576 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2577 DEBUG(10, ("Got netbios keepalive\n"));
2579 * Just swallow it
2581 return true;
2584 if (inbuf_len < smb_size) {
2585 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2586 return false;
2588 if (!valid_smb_header(inbuf)) {
2589 DEBUG(10, ("Got invalid SMB header\n"));
2590 return false;
2593 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2594 seqnum)) {
2595 return false;
2597 req.inbuf = inbuf;
2599 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2600 smb_messages[req.cmd].name
2601 ? smb_messages[req.cmd].name : "unknown"));
2603 if (req.cmd != SMBecho) {
2604 return false;
2606 if (req.wct < 1) {
2607 return false;
2610 num_replies = SVAL(req.vwv+0, 0);
2611 if (num_replies != 1) {
2612 /* Not a Windows "Hey, you're still there?" request */
2613 return false;
2616 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2617 1, req.buflen)) {
2618 DEBUG(10, ("create_outbuf failed\n"));
2619 return false;
2621 req.outbuf = (uint8_t *)outbuf;
2623 SSVAL(req.outbuf, smb_vwv0, num_replies);
2625 if (req.buflen > 0) {
2626 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2629 out_len = smb_len(req.outbuf) + 4;
2631 ok = srv_send_smb(req.sconn,
2632 (char *)outbuf,
2633 true, seqnum+1,
2634 false, &req.pcd);
2635 TALLOC_FREE(outbuf);
2636 if (!ok) {
2637 exit(1);
2640 return true;
2643 static void smbd_echo_exit(struct tevent_context *ev,
2644 struct tevent_fd *fde, uint16_t flags,
2645 void *private_data)
2647 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2648 exit(0);
2651 static void smbd_echo_reader(struct tevent_context *ev,
2652 struct tevent_fd *fde, uint16_t flags,
2653 void *private_data)
2655 struct smbd_echo_state *state = talloc_get_type_abort(
2656 private_data, struct smbd_echo_state);
2657 struct smbd_server_connection *sconn = state->sconn;
2658 size_t unread, num_pending;
2659 NTSTATUS status;
2660 struct iovec *tmp;
2661 size_t iov_len;
2662 uint32_t seqnum = 0;
2663 bool reply;
2664 bool ok;
2665 bool encrypted = false;
2667 smb_msleep(1000);
2669 ok = smbd_lock_socket_internal(sconn);
2670 if (!ok) {
2671 DEBUG(0, ("%s: failed to lock socket\n",
2672 __location__));
2673 exit(1);
2676 if (!fd_is_readable(sconn->sock)) {
2677 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2678 (int)sys_getpid()));
2679 ok = smbd_unlock_socket_internal(sconn);
2680 if (!ok) {
2681 DEBUG(1, ("%s: failed to unlock socket in\n",
2682 __location__));
2683 exit(1);
2685 return;
2688 num_pending = talloc_array_length(state->pending);
2689 tmp = talloc_realloc(state, state->pending, struct iovec,
2690 num_pending+1);
2691 if (tmp == NULL) {
2692 DEBUG(1, ("talloc_realloc failed\n"));
2693 exit(1);
2695 state->pending = tmp;
2697 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2699 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2700 (char **)(void *)&state->pending[num_pending].iov_base,
2701 0 /* timeout */,
2702 &unread,
2703 &encrypted,
2704 &iov_len,
2705 &seqnum,
2706 false /* trusted_channel*/);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2709 (int)sys_getpid(), nt_errstr(status)));
2710 exit(1);
2712 state->pending[num_pending].iov_len = iov_len;
2714 ok = smbd_unlock_socket_internal(sconn);
2715 if (!ok) {
2716 DEBUG(1, ("%s: failed to unlock socket in\n",
2717 __location__));
2718 exit(1);
2721 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2722 state->pending[num_pending].iov_len,
2723 seqnum);
2724 if (reply) {
2725 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2726 /* no check, shrinking by some bytes does not fail */
2727 state->pending = talloc_realloc(state, state->pending,
2728 struct iovec,
2729 num_pending);
2730 return;
2733 if (state->pending[num_pending].iov_len >= smb_size) {
2735 * place the seqnum in the packet so that the main process
2736 * can reply with signing
2738 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2739 smb_ss_field, seqnum);
2740 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2741 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2744 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2745 smbd_echo_activate_writer(state);
2748 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2749 int parent_pipe)
2751 struct smbd_echo_state *state;
2753 state = talloc_zero(sconn, struct smbd_echo_state);
2754 if (state == NULL) {
2755 DEBUG(1, ("talloc failed\n"));
2756 return;
2758 state->sconn = sconn;
2759 state->parent_pipe = parent_pipe;
2760 state->ev = s3_tevent_context_init(state);
2761 if (state->ev == NULL) {
2762 DEBUG(1, ("tevent_context_init failed\n"));
2763 TALLOC_FREE(state);
2764 return;
2766 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2767 TEVENT_FD_READ, smbd_echo_exit,
2768 state);
2769 if (state->parent_fde == NULL) {
2770 DEBUG(1, ("tevent_add_fd failed\n"));
2771 TALLOC_FREE(state);
2772 return;
2774 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2775 TEVENT_FD_READ, smbd_echo_reader,
2776 state);
2777 if (state->read_fde == NULL) {
2778 DEBUG(1, ("tevent_add_fd failed\n"));
2779 TALLOC_FREE(state);
2780 return;
2783 while (true) {
2784 if (tevent_loop_once(state->ev) == -1) {
2785 DEBUG(1, ("tevent_loop_once failed: %s\n",
2786 strerror(errno)));
2787 break;
2790 TALLOC_FREE(state);
2794 * Handle SMBecho requests in a forked child process
2796 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2798 int listener_pipe[2];
2799 int res;
2800 pid_t child;
2802 res = pipe(listener_pipe);
2803 if (res == -1) {
2804 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2805 return false;
2807 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2808 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2809 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2810 goto fail;
2813 child = sys_fork();
2814 if (child == 0) {
2815 NTSTATUS status;
2817 close(listener_pipe[0]);
2818 set_blocking(listener_pipe[1], false);
2820 status = reinit_after_fork(sconn->msg_ctx,
2821 smbd_event_context(),
2822 procid_self(), false);
2823 if (!NT_STATUS_IS_OK(status)) {
2824 DEBUG(1, ("reinit_after_fork failed: %s\n",
2825 nt_errstr(status)));
2826 exit(1);
2828 smbd_echo_loop(sconn, listener_pipe[1]);
2829 exit(0);
2831 close(listener_pipe[1]);
2832 listener_pipe[1] = -1;
2833 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2835 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2838 * Without smb signing this is the same as the normal smbd
2839 * listener. This needs to change once signing comes in.
2841 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2842 sconn,
2843 sconn->smb1.echo_handler.trusted_fd,
2844 EVENT_FD_READ,
2845 smbd_server_echo_handler,
2846 sconn);
2847 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2848 DEBUG(1, ("event_add_fd failed\n"));
2849 goto fail;
2852 return true;
2854 fail:
2855 if (listener_pipe[0] != -1) {
2856 close(listener_pipe[0]);
2858 if (listener_pipe[1] != -1) {
2859 close(listener_pipe[1]);
2861 sconn->smb1.echo_handler.trusted_fd = -1;
2862 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2863 close(sconn->smb1.echo_handler.socket_lock_fd);
2865 sconn->smb1.echo_handler.trusted_fd = -1;
2866 sconn->smb1.echo_handler.socket_lock_fd = -1;
2867 return false;
2870 #if CLUSTER_SUPPORT
2872 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2873 struct sockaddr_storage *srv,
2874 struct sockaddr_storage *clnt)
2876 struct ctdbd_connection *cconn;
2877 char tmp_addr[INET6_ADDRSTRLEN];
2878 char *addr;
2880 cconn = messaging_ctdbd_connection();
2881 if (cconn == NULL) {
2882 return NT_STATUS_NO_MEMORY;
2885 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2886 addr = talloc_strdup(cconn, tmp_addr);
2887 if (addr == NULL) {
2888 return NT_STATUS_NO_MEMORY;
2890 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2893 #endif
2895 /****************************************************************************
2896 Process commands from the client
2897 ****************************************************************************/
2899 void smbd_process(struct smbd_server_connection *sconn)
2901 TALLOC_CTX *frame = talloc_stackframe();
2902 struct sockaddr_storage ss;
2903 struct sockaddr *sa = NULL;
2904 socklen_t sa_socklen;
2905 struct tsocket_address *local_address = NULL;
2906 struct tsocket_address *remote_address = NULL;
2907 const char *remaddr = NULL;
2908 int ret;
2910 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2911 !lp_async_smb_echo_handler()) {
2913 * We're not making the decision here,
2914 * we're just allowing the client
2915 * to decide between SMB1 and SMB2
2916 * with the first negprot
2917 * packet.
2919 sconn->using_smb2 = true;
2922 /* Ensure child is set to blocking mode */
2923 set_blocking(sconn->sock,True);
2925 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2926 set_socket_options(sconn->sock, lp_socket_options());
2928 sa = (struct sockaddr *)(void *)&ss;
2929 sa_socklen = sizeof(ss);
2930 ret = getpeername(sconn->sock, sa, &sa_socklen);
2931 if (ret != 0) {
2932 int level = (errno == ENOTCONN)?2:0;
2933 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2934 exit_server_cleanly("getpeername() failed.\n");
2936 ret = tsocket_address_bsd_from_sockaddr(sconn,
2937 sa, sa_socklen,
2938 &remote_address);
2939 if (ret != 0) {
2940 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2941 __location__, strerror(errno)));
2942 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2945 sa = (struct sockaddr *)(void *)&ss;
2946 sa_socklen = sizeof(ss);
2947 ret = getsockname(sconn->sock, sa, &sa_socklen);
2948 if (ret != 0) {
2949 int level = (errno == ENOTCONN)?2:0;
2950 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2951 exit_server_cleanly("getsockname() failed.\n");
2953 ret = tsocket_address_bsd_from_sockaddr(sconn,
2954 sa, sa_socklen,
2955 &local_address);
2956 if (ret != 0) {
2957 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2958 __location__, strerror(errno)));
2959 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2962 sconn->local_address = local_address;
2963 sconn->remote_address = remote_address;
2965 if (tsocket_address_is_inet(remote_address, "ip")) {
2966 remaddr = tsocket_address_inet_addr_string(
2967 sconn->remote_address,
2968 talloc_tos());
2969 if (remaddr == NULL) {
2972 } else {
2973 remaddr = "0.0.0.0";
2976 /* this is needed so that we get decent entries
2977 in smbstatus for port 445 connects */
2978 set_remote_machine_name(remaddr, false);
2979 reload_services(sconn->msg_ctx, sconn->sock, true);
2982 * Before the first packet, check the global hosts allow/ hosts deny
2983 * parameters before doing any parsing of packets passed to us by the
2984 * client. This prevents attacks on our parsing code from hosts not in
2985 * the hosts allow list.
2988 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2989 sconn->client_id.name,
2990 sconn->client_id.addr)) {
2992 * send a negative session response "not listening on calling
2993 * name"
2995 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2996 DEBUG( 1, ("Connection denied from %s to %s\n",
2997 tsocket_address_string(remote_address, talloc_tos()),
2998 tsocket_address_string(local_address, talloc_tos())));
2999 (void)srv_send_smb(sconn,(char *)buf, false,
3000 0, false, NULL);
3001 exit_server_cleanly("connection denied");
3004 DEBUG(10, ("Connection allowed from %s to %s\n",
3005 tsocket_address_string(remote_address, talloc_tos()),
3006 tsocket_address_string(local_address, talloc_tos())));
3008 init_modules();
3010 smb_perfcount_init();
3012 if (!init_account_policy()) {
3013 exit_server("Could not open account policy tdb.\n");
3016 if (*lp_rootdir()) {
3017 if (chroot(lp_rootdir()) != 0) {
3018 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3019 exit_server("Failed to chroot()");
3021 if (chdir("/") == -1) {
3022 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3023 exit_server("Failed to chroot()");
3025 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3028 if (!srv_init_signing(sconn)) {
3029 exit_server("Failed to init smb_signing");
3032 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3033 exit_server("Failed to fork echo handler");
3036 /* Setup oplocks */
3037 if (!init_oplocks(sconn->msg_ctx))
3038 exit_server("Failed to init oplocks");
3040 /* register our message handlers */
3041 messaging_register(sconn->msg_ctx, NULL,
3042 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3043 messaging_register(sconn->msg_ctx, sconn,
3044 MSG_SMB_RELEASE_IP, msg_release_ip);
3045 messaging_register(sconn->msg_ctx, NULL,
3046 MSG_SMB_CLOSE_FILE, msg_close_file);
3049 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3050 * MSGs to all child processes
3052 messaging_deregister(sconn->msg_ctx,
3053 MSG_DEBUG, NULL);
3054 messaging_register(sconn->msg_ctx, NULL,
3055 MSG_DEBUG, debug_message);
3057 if ((lp_keepalive() != 0)
3058 && !(event_add_idle(smbd_event_context(), NULL,
3059 timeval_set(lp_keepalive(), 0),
3060 "keepalive", keepalive_fn,
3061 NULL))) {
3062 DEBUG(0, ("Could not add keepalive event\n"));
3063 exit(1);
3066 if (!(event_add_idle(smbd_event_context(), NULL,
3067 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3068 "deadtime", deadtime_fn, sconn))) {
3069 DEBUG(0, ("Could not add deadtime event\n"));
3070 exit(1);
3073 if (!(event_add_idle(smbd_event_context(), NULL,
3074 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3075 "housekeeping", housekeeping_fn, sconn))) {
3076 DEBUG(0, ("Could not add housekeeping event\n"));
3077 exit(1);
3080 #ifdef CLUSTER_SUPPORT
3082 if (lp_clustering()) {
3084 * We need to tell ctdb about our client's TCP
3085 * connection, so that for failover ctdbd can send
3086 * tickle acks, triggering a reconnection by the
3087 * client.
3090 struct sockaddr_storage srv, clnt;
3092 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3093 NTSTATUS status;
3094 status = smbd_register_ips(sconn, &srv, &clnt);
3095 if (!NT_STATUS_IS_OK(status)) {
3096 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3097 nt_errstr(status)));
3099 } else
3101 DEBUG(0,("Unable to get tcp info for "
3102 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3103 strerror(errno)));
3107 #endif
3109 sconn->nbt.got_session = false;
3111 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3113 sconn->smb1.sessions.done_sesssetup = false;
3114 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3115 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3116 /* users from session setup */
3117 sconn->smb1.sessions.session_userlist = NULL;
3118 /* workgroup from session setup. */
3119 sconn->smb1.sessions.session_workgroup = NULL;
3120 /* this holds info on user ids that are already validated for this VC */
3121 sconn->smb1.sessions.validated_users = NULL;
3122 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3123 sconn->smb1.sessions.num_validated_vuids = 0;
3125 conn_init(sconn);
3126 if (!init_dptrs(sconn)) {
3127 exit_server("init_dptrs() failed");
3130 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3131 sconn,
3132 sconn->sock,
3133 EVENT_FD_READ,
3134 smbd_server_connection_handler,
3135 sconn);
3136 if (!sconn->smb1.fde) {
3137 exit_server("failed to create smbd_server_connection fde");
3140 TALLOC_FREE(frame);
3142 while (True) {
3143 NTSTATUS status;
3145 frame = talloc_stackframe_pool(8192);
3147 errno = 0;
3149 status = smbd_server_connection_loop_once(sconn);
3150 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3151 !NT_STATUS_IS_OK(status)) {
3152 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3153 " exiting\n", nt_errstr(status)));
3154 break;
3157 TALLOC_FREE(frame);
3160 exit_server_cleanly(NULL);
3163 bool req_is_in_chain(struct smb_request *req)
3165 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3167 * We're right now handling a subsequent request, so we must
3168 * be in a chain
3170 return true;
3173 if (!is_andx_req(req->cmd)) {
3174 return false;
3177 if (req->wct < 2) {
3179 * Okay, an illegal request, but definitely not chained :-)
3181 return false;
3184 return (CVAL(req->vwv+0, 0) != 0xFF);