s3: Handle EINTR from sys_poll correctly
[Samba.git] / source3 / smbd / process.c
blob98de361d75cfa74efcf258ea945b6bb9834b699d
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"
37 extern bool global_machine_password_needs_changing;
39 static void construct_reply_common(struct smb_request *req, const char *inbuf,
40 char *outbuf);
41 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
43 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
45 bool ok;
47 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
48 return true;
51 sconn->smb1.echo_handler.ref_count++;
53 if (sconn->smb1.echo_handler.ref_count > 1) {
54 return true;
57 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
59 do {
60 ok = fcntl_lock(
61 sconn->smb1.echo_handler.socket_lock_fd,
62 SMB_F_SETLKW, 0, 0, F_WRLCK);
63 } while (!ok && (errno == EINTR));
65 if (!ok) {
66 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
67 return false;
70 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
72 return true;
75 void smbd_lock_socket(struct smbd_server_connection *sconn)
77 if (!smbd_lock_socket_internal(sconn)) {
78 exit_server_cleanly("failed to lock socket");
82 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
84 bool ok;
86 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
87 return true;
90 sconn->smb1.echo_handler.ref_count--;
92 if (sconn->smb1.echo_handler.ref_count > 0) {
93 return true;
96 do {
97 ok = fcntl_lock(
98 sconn->smb1.echo_handler.socket_lock_fd,
99 SMB_F_SETLKW, 0, 0, F_UNLCK);
100 } while (!ok && (errno == EINTR));
102 if (!ok) {
103 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
104 return false;
107 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
109 return true;
112 void smbd_unlock_socket(struct smbd_server_connection *sconn)
114 if (!smbd_unlock_socket_internal(sconn)) {
115 exit_server_cleanly("failed to unlock socket");
119 /* Accessor function for smb_read_error for smbd functions. */
121 /****************************************************************************
122 Send an smb to a fd.
123 ****************************************************************************/
125 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
126 bool do_signing, uint32_t seqnum,
127 bool do_encrypt,
128 struct smb_perfcount_data *pcd)
130 size_t len = 0;
131 size_t nwritten=0;
132 ssize_t ret;
133 char *buf_out = buffer;
135 smbd_lock_socket(sconn);
137 if (do_signing) {
138 /* Sign the outgoing packet if required. */
139 srv_calculate_sign_mac(sconn, buf_out, seqnum);
142 if (do_encrypt) {
143 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
144 if (!NT_STATUS_IS_OK(status)) {
145 DEBUG(0, ("send_smb: SMB encryption failed "
146 "on outgoing packet! Error %s\n",
147 nt_errstr(status) ));
148 goto out;
152 len = smb_len(buf_out) + 4;
154 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
155 if (ret <= 0) {
157 char addr[INET6_ADDRSTRLEN];
159 * Try and give an error message saying what
160 * client failed.
162 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
163 (int)sys_getpid(), (int)len,
164 get_peer_addr(sconn->sock, addr, sizeof(addr)),
165 (int)ret, strerror(errno) ));
167 srv_free_enc_buffer(buf_out);
168 goto out;
171 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
172 srv_free_enc_buffer(buf_out);
173 out:
174 SMB_PERFCOUNT_END(pcd);
176 smbd_unlock_socket(sconn);
177 return true;
180 /*******************************************************************
181 Setup the word count and byte count for a smb message.
182 ********************************************************************/
184 int srv_set_message(char *buf,
185 int num_words,
186 int num_bytes,
187 bool zero)
189 if (zero && (num_words || num_bytes)) {
190 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
192 SCVAL(buf,smb_wct,num_words);
193 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
194 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
195 return (smb_size + num_words*2 + num_bytes);
198 static bool valid_smb_header(const uint8_t *inbuf)
200 if (is_encrypted_packet(inbuf)) {
201 return true;
204 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
205 * but it just looks weird to call strncmp for this one.
207 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
210 /* Socket functions for smbd packet processing. */
212 static bool valid_packet_size(size_t len)
215 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
216 * of header. Don't print the error if this fits.... JRA.
219 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
220 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
221 (unsigned long)len));
222 return false;
224 return true;
227 static NTSTATUS read_packet_remainder(int fd, char *buffer,
228 unsigned int timeout, ssize_t len)
230 NTSTATUS status;
232 if (len <= 0) {
233 return NT_STATUS_OK;
236 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
237 if (!NT_STATUS_IS_OK(status)) {
238 char addr[INET6_ADDRSTRLEN];
239 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
240 "error = %s.\n",
241 get_peer_addr(fd, addr, sizeof(addr)),
242 nt_errstr(status)));
244 return status;
247 /****************************************************************************
248 Attempt a zerocopy writeX read. We know here that len > smb_size-4
249 ****************************************************************************/
252 * Unfortunately, earlier versions of smbclient/libsmbclient
253 * don't send this "standard" writeX header. I've fixed this
254 * for 3.2 but we'll use the old method with earlier versions.
255 * Windows and CIFSFS at least use this standard size. Not
256 * sure about MacOSX.
259 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
260 (2*14) + /* word count (including bcc) */ \
261 1 /* pad byte */)
263 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
264 const char lenbuf[4],
265 struct smbd_server_connection *sconn,
266 int sock,
267 char **buffer,
268 unsigned int timeout,
269 size_t *p_unread,
270 size_t *len_ret)
272 /* Size of a WRITEX call (+4 byte len). */
273 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
274 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
275 ssize_t toread;
276 NTSTATUS status;
278 memcpy(writeX_header, lenbuf, 4);
280 status = read_fd_with_timeout(
281 sock, writeX_header + 4,
282 STANDARD_WRITE_AND_X_HEADER_SIZE,
283 STANDARD_WRITE_AND_X_HEADER_SIZE,
284 timeout, NULL);
286 if (!NT_STATUS_IS_OK(status)) {
287 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
288 "error = %s.\n", sconn->client_id.addr,
289 nt_errstr(status)));
290 return status;
294 * Ok - now try and see if this is a possible
295 * valid writeX call.
298 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
300 * If the data offset is beyond what
301 * we've read, drain the extra bytes.
303 uint16_t doff = SVAL(writeX_header,smb_vwv11);
304 ssize_t newlen;
306 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
307 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
308 if (drain_socket(sock, drain) != drain) {
309 smb_panic("receive_smb_raw_talloc_partial_read:"
310 " failed to drain pending bytes");
312 } else {
313 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
316 /* Spoof down the length and null out the bcc. */
317 set_message_bcc(writeX_header, 0);
318 newlen = smb_len(writeX_header);
320 /* Copy the header we've written. */
322 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
323 writeX_header,
324 sizeof(writeX_header));
326 if (*buffer == NULL) {
327 DEBUG(0, ("Could not allocate inbuf of length %d\n",
328 (int)sizeof(writeX_header)));
329 return NT_STATUS_NO_MEMORY;
332 /* Work out the remaining bytes. */
333 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
334 *len_ret = newlen + 4;
335 return NT_STATUS_OK;
338 if (!valid_packet_size(len)) {
339 return NT_STATUS_INVALID_PARAMETER;
343 * Not a valid writeX call. Just do the standard
344 * talloc and return.
347 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
349 if (*buffer == NULL) {
350 DEBUG(0, ("Could not allocate inbuf of length %d\n",
351 (int)len+4));
352 return NT_STATUS_NO_MEMORY;
355 /* Copy in what we already read. */
356 memcpy(*buffer,
357 writeX_header,
358 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
359 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
361 if(toread > 0) {
362 status = read_packet_remainder(
363 sock,
364 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
365 timeout, toread);
367 if (!NT_STATUS_IS_OK(status)) {
368 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
369 nt_errstr(status)));
370 return status;
374 *len_ret = len + 4;
375 return NT_STATUS_OK;
378 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
379 struct smbd_server_connection *sconn,
380 int sock,
381 char **buffer, unsigned int timeout,
382 size_t *p_unread, size_t *plen)
384 char lenbuf[4];
385 size_t len;
386 int min_recv_size = lp_min_receive_file_size();
387 NTSTATUS status;
389 *p_unread = 0;
391 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
392 &len);
393 if (!NT_STATUS_IS_OK(status)) {
394 return status;
397 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
398 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
399 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
400 !srv_is_signing_active(sconn) &&
401 sconn->smb1.echo_handler.trusted_fde == NULL) {
403 return receive_smb_raw_talloc_partial_read(
404 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
405 p_unread, plen);
408 if (!valid_packet_size(len)) {
409 return NT_STATUS_INVALID_PARAMETER;
413 * The +4 here can't wrap, we've checked the length above already.
416 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
418 if (*buffer == NULL) {
419 DEBUG(0, ("Could not allocate inbuf of length %d\n",
420 (int)len+4));
421 return NT_STATUS_NO_MEMORY;
424 memcpy(*buffer, lenbuf, sizeof(lenbuf));
426 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
427 if (!NT_STATUS_IS_OK(status)) {
428 return status;
431 *plen = len + 4;
432 return NT_STATUS_OK;
435 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
436 struct smbd_server_connection *sconn,
437 int sock,
438 char **buffer, unsigned int timeout,
439 size_t *p_unread, bool *p_encrypted,
440 size_t *p_len,
441 uint32_t *seqnum,
442 bool trusted_channel)
444 size_t len = 0;
445 NTSTATUS status;
447 *p_encrypted = false;
449 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
450 p_unread, &len);
451 if (!NT_STATUS_IS_OK(status)) {
452 DEBUG(1, ("read_smb_length_return_keepalive failed for "
453 "client %s read error = %s.\n",
454 sconn->client_id.addr, nt_errstr(status)));
455 return status;
458 if (is_encrypted_packet((uint8_t *)*buffer)) {
459 status = srv_decrypt_buffer(*buffer);
460 if (!NT_STATUS_IS_OK(status)) {
461 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
462 "incoming packet! Error %s\n",
463 nt_errstr(status) ));
464 return status;
466 *p_encrypted = true;
469 /* Check the incoming SMB signature. */
470 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
471 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
472 "incoming packet!\n"));
473 return NT_STATUS_INVALID_NETWORK_RESPONSE;
476 *p_len = len;
477 return NT_STATUS_OK;
481 * Initialize a struct smb_request from an inbuf
484 static bool init_smb_request(struct smb_request *req,
485 struct smbd_server_connection *sconn,
486 const uint8 *inbuf,
487 size_t unread_bytes, bool encrypted,
488 uint32_t seqnum)
490 size_t req_size = smb_len(inbuf) + 4;
491 /* Ensure we have at least smb_size bytes. */
492 if (req_size < smb_size) {
493 DEBUG(0,("init_smb_request: invalid request size %u\n",
494 (unsigned int)req_size ));
495 return false;
497 req->cmd = CVAL(inbuf, smb_com);
498 req->flags2 = SVAL(inbuf, smb_flg2);
499 req->smbpid = SVAL(inbuf, smb_pid);
500 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
501 req->seqnum = seqnum;
502 req->vuid = SVAL(inbuf, smb_uid);
503 req->tid = SVAL(inbuf, smb_tid);
504 req->wct = CVAL(inbuf, smb_wct);
505 req->vwv = (uint16_t *)(inbuf+smb_vwv);
506 req->buflen = smb_buflen(inbuf);
507 req->buf = (const uint8_t *)smb_buf(inbuf);
508 req->unread_bytes = unread_bytes;
509 req->encrypted = encrypted;
510 req->sconn = sconn;
511 req->conn = conn_find(sconn,req->tid);
512 req->chain_fsp = NULL;
513 req->chain_outbuf = NULL;
514 req->done = false;
515 req->smb2req = NULL;
516 smb_init_perfcount_data(&req->pcd);
518 /* Ensure we have at least wct words and 2 bytes of bcc. */
519 if (smb_size + req->wct*2 > req_size) {
520 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
521 (unsigned int)req->wct,
522 (unsigned int)req_size));
523 return false;
525 /* Ensure bcc is correct. */
526 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
527 DEBUG(0,("init_smb_request: invalid bcc number %u "
528 "(wct = %u, size %u)\n",
529 (unsigned int)req->buflen,
530 (unsigned int)req->wct,
531 (unsigned int)req_size));
532 return false;
535 req->outbuf = NULL;
536 return true;
539 static void process_smb(struct smbd_server_connection *conn,
540 uint8_t *inbuf, size_t nread, size_t unread_bytes,
541 uint32_t seqnum, bool encrypted,
542 struct smb_perfcount_data *deferred_pcd);
544 static void smbd_deferred_open_timer(struct event_context *ev,
545 struct timed_event *te,
546 struct timeval _tval,
547 void *private_data)
549 struct pending_message_list *msg = talloc_get_type(private_data,
550 struct pending_message_list);
551 TALLOC_CTX *mem_ctx = talloc_tos();
552 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
553 uint8_t *inbuf;
555 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
556 msg->buf.length);
557 if (inbuf == NULL) {
558 exit_server("smbd_deferred_open_timer: talloc failed\n");
559 return;
562 /* We leave this message on the queue so the open code can
563 know this is a retry. */
564 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
565 (unsigned long long)mid ));
567 /* Mark the message as processed so this is not
568 * re-processed in error. */
569 msg->processed = true;
571 process_smb(smbd_server_conn, inbuf,
572 msg->buf.length, 0,
573 msg->seqnum, msg->encrypted, &msg->pcd);
575 /* If it's still there and was processed, remove it. */
576 msg = get_deferred_open_message_smb(mid);
577 if (msg && msg->processed) {
578 remove_deferred_open_message_smb(mid);
582 /****************************************************************************
583 Function to push a message onto the tail of a linked list of smb messages ready
584 for processing.
585 ****************************************************************************/
587 static bool push_queued_message(struct smb_request *req,
588 struct timeval request_time,
589 struct timeval end_time,
590 char *private_data, size_t private_len)
592 int msg_len = smb_len(req->inbuf) + 4;
593 struct pending_message_list *msg;
595 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
597 if(msg == NULL) {
598 DEBUG(0,("push_message: malloc fail (1)\n"));
599 return False;
602 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
603 if(msg->buf.data == NULL) {
604 DEBUG(0,("push_message: malloc fail (2)\n"));
605 TALLOC_FREE(msg);
606 return False;
609 msg->request_time = request_time;
610 msg->seqnum = req->seqnum;
611 msg->encrypted = req->encrypted;
612 msg->processed = false;
613 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
615 if (private_data) {
616 msg->private_data = data_blob_talloc(msg, private_data,
617 private_len);
618 if (msg->private_data.data == NULL) {
619 DEBUG(0,("push_message: malloc fail (3)\n"));
620 TALLOC_FREE(msg);
621 return False;
625 msg->te = event_add_timed(smbd_event_context(),
626 msg,
627 end_time,
628 smbd_deferred_open_timer,
629 msg);
630 if (!msg->te) {
631 DEBUG(0,("push_message: event_add_timed failed\n"));
632 TALLOC_FREE(msg);
633 return false;
636 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
638 DEBUG(10,("push_message: pushed message length %u on "
639 "deferred_open_queue\n", (unsigned int)msg_len));
641 return True;
644 /****************************************************************************
645 Function to delete a sharing violation open message by mid.
646 ****************************************************************************/
648 void remove_deferred_open_message_smb(uint64_t mid)
650 struct pending_message_list *pml;
652 if (smbd_server_conn->using_smb2) {
653 remove_deferred_open_message_smb2(smbd_server_conn, mid);
654 return;
657 for (pml = deferred_open_queue; pml; pml = pml->next) {
658 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
659 DEBUG(10,("remove_deferred_open_message_smb: "
660 "deleting mid %llu len %u\n",
661 (unsigned long long)mid,
662 (unsigned int)pml->buf.length ));
663 DLIST_REMOVE(deferred_open_queue, pml);
664 TALLOC_FREE(pml);
665 return;
670 /****************************************************************************
671 Move a sharing violation open retry message to the front of the list and
672 schedule it for immediate processing.
673 ****************************************************************************/
675 void schedule_deferred_open_message_smb(uint64_t mid)
677 struct pending_message_list *pml;
678 int i = 0;
680 if (smbd_server_conn->using_smb2) {
681 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
682 return;
685 for (pml = deferred_open_queue; pml; pml = pml->next) {
686 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
688 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
689 "msg_mid = %llu\n",
690 i++,
691 (unsigned long long)msg_mid ));
693 if (mid == msg_mid) {
694 struct timed_event *te;
696 if (pml->processed) {
697 /* A processed message should not be
698 * rescheduled. */
699 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
700 "message mid %llu was already processed\n",
701 (unsigned long long)msg_mid ));
702 continue;
705 DEBUG(10,("schedule_deferred_open_message_smb: "
706 "scheduling mid %llu\n",
707 (unsigned long long)mid ));
709 te = event_add_timed(smbd_event_context(),
710 pml,
711 timeval_zero(),
712 smbd_deferred_open_timer,
713 pml);
714 if (!te) {
715 DEBUG(10,("schedule_deferred_open_message_smb: "
716 "event_add_timed() failed, "
717 "skipping mid %llu\n",
718 (unsigned long long)msg_mid ));
721 TALLOC_FREE(pml->te);
722 pml->te = te;
723 DLIST_PROMOTE(deferred_open_queue, pml);
724 return;
728 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
729 "find message mid %llu\n",
730 (unsigned long long)mid ));
733 /****************************************************************************
734 Return true if this mid is on the deferred queue and was not yet processed.
735 ****************************************************************************/
737 bool open_was_deferred(uint64_t mid)
739 struct pending_message_list *pml;
741 if (smbd_server_conn->using_smb2) {
742 return open_was_deferred_smb2(smbd_server_conn, mid);
745 for (pml = deferred_open_queue; pml; pml = pml->next) {
746 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
747 return True;
750 return False;
753 /****************************************************************************
754 Return the message queued by this mid.
755 ****************************************************************************/
757 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
759 struct pending_message_list *pml;
761 for (pml = deferred_open_queue; pml; pml = pml->next) {
762 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
763 return pml;
766 return NULL;
769 /****************************************************************************
770 Get the state data queued by this mid.
771 ****************************************************************************/
773 bool get_deferred_open_message_state(struct smb_request *smbreq,
774 struct timeval *p_request_time,
775 void **pp_state)
777 struct pending_message_list *pml;
779 if (smbd_server_conn->using_smb2) {
780 return get_deferred_open_message_state_smb2(smbreq->smb2req,
781 p_request_time,
782 pp_state);
785 pml = get_deferred_open_message_smb(smbreq->mid);
786 if (!pml) {
787 return false;
789 if (p_request_time) {
790 *p_request_time = pml->request_time;
792 if (pp_state) {
793 *pp_state = (void *)pml->private_data.data;
795 return true;
798 /****************************************************************************
799 Function to push a deferred open smb message onto a linked list of local smb
800 messages ready for processing.
801 ****************************************************************************/
803 bool push_deferred_open_message_smb(struct smb_request *req,
804 struct timeval request_time,
805 struct timeval timeout,
806 struct file_id id,
807 char *private_data, size_t priv_len)
809 struct timeval end_time;
811 if (req->smb2req) {
812 return push_deferred_open_message_smb2(req->smb2req,
813 request_time,
814 timeout,
816 private_data,
817 priv_len);
820 if (req->unread_bytes) {
821 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
822 "unread_bytes = %u\n",
823 (unsigned int)req->unread_bytes ));
824 smb_panic("push_deferred_open_message_smb: "
825 "logic error unread_bytes != 0" );
828 end_time = timeval_sum(&request_time, &timeout);
830 DEBUG(10,("push_deferred_open_message_smb: pushing message "
831 "len %u mid %llu timeout time [%u.%06u]\n",
832 (unsigned int) smb_len(req->inbuf)+4,
833 (unsigned long long)req->mid,
834 (unsigned int)end_time.tv_sec,
835 (unsigned int)end_time.tv_usec));
837 return push_queued_message(req, request_time, end_time,
838 private_data, priv_len);
841 struct idle_event {
842 struct timed_event *te;
843 struct timeval interval;
844 char *name;
845 bool (*handler)(const struct timeval *now, void *private_data);
846 void *private_data;
849 static void smbd_idle_event_handler(struct event_context *ctx,
850 struct timed_event *te,
851 struct timeval now,
852 void *private_data)
854 struct idle_event *event =
855 talloc_get_type_abort(private_data, struct idle_event);
857 TALLOC_FREE(event->te);
859 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
860 event->name, event->te));
862 if (!event->handler(&now, event->private_data)) {
863 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
864 event->name, event->te));
865 /* Don't repeat, delete ourselves */
866 TALLOC_FREE(event);
867 return;
870 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
871 event->name, event->te));
873 event->te = event_add_timed(ctx, event,
874 timeval_sum(&now, &event->interval),
875 smbd_idle_event_handler, event);
877 /* We can't do much but fail here. */
878 SMB_ASSERT(event->te != NULL);
881 struct idle_event *event_add_idle(struct event_context *event_ctx,
882 TALLOC_CTX *mem_ctx,
883 struct timeval interval,
884 const char *name,
885 bool (*handler)(const struct timeval *now,
886 void *private_data),
887 void *private_data)
889 struct idle_event *result;
890 struct timeval now = timeval_current();
892 result = TALLOC_P(mem_ctx, struct idle_event);
893 if (result == NULL) {
894 DEBUG(0, ("talloc failed\n"));
895 return NULL;
898 result->interval = interval;
899 result->handler = handler;
900 result->private_data = private_data;
902 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
903 DEBUG(0, ("talloc failed\n"));
904 TALLOC_FREE(result);
905 return NULL;
908 result->te = event_add_timed(event_ctx, result,
909 timeval_sum(&now, &interval),
910 smbd_idle_event_handler, result);
911 if (result->te == NULL) {
912 DEBUG(0, ("event_add_timed failed\n"));
913 TALLOC_FREE(result);
914 return NULL;
917 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
918 return result;
921 static void smbd_sig_term_handler(struct tevent_context *ev,
922 struct tevent_signal *se,
923 int signum,
924 int count,
925 void *siginfo,
926 void *private_data)
928 exit_server_cleanly("termination signal");
931 void smbd_setup_sig_term_handler(void)
933 struct tevent_signal *se;
935 se = tevent_add_signal(smbd_event_context(),
936 smbd_event_context(),
937 SIGTERM, 0,
938 smbd_sig_term_handler,
939 NULL);
940 if (!se) {
941 exit_server("failed to setup SIGTERM handler");
945 static void smbd_sig_hup_handler(struct tevent_context *ev,
946 struct tevent_signal *se,
947 int signum,
948 int count,
949 void *siginfo,
950 void *private_data)
952 struct messaging_context *msg_ctx = talloc_get_type_abort(
953 private_data, struct messaging_context);
954 change_to_root_user();
955 DEBUG(1,("Reloading services after SIGHUP\n"));
956 reload_services(msg_ctx, smbd_server_conn->sock, False);
957 if (am_parent) {
958 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
962 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
963 struct messaging_context *msg_ctx)
965 struct tevent_signal *se;
967 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
968 msg_ctx);
969 if (!se) {
970 exit_server("failed to setup SIGHUP handler");
974 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
976 int timeout;
977 int num_pfds = 0;
978 int ret;
979 bool retry;
981 timeout = SMBD_SELECT_TIMEOUT * 1000;
984 * Are there any timed events waiting ? If so, ensure we don't
985 * select for longer than it would take to wait for them.
988 event_add_to_poll_args(smbd_event_context(), conn,
989 &conn->pfds, &num_pfds, &timeout);
991 /* Process a signal and timed events now... */
992 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
993 return NT_STATUS_RETRY;
997 int sav;
998 START_PROFILE(smbd_idle);
1000 ret = sys_poll(conn->pfds, num_pfds, timeout);
1001 sav = errno;
1003 END_PROFILE(smbd_idle);
1004 errno = sav;
1007 if (ret == -1) {
1008 if (errno == EINTR) {
1009 return NT_STATUS_RETRY;
1011 return map_nt_error_from_unix(errno);
1014 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1015 num_pfds);
1016 if (retry) {
1017 return NT_STATUS_RETRY;
1020 /* Did we timeout ? */
1021 if (ret == 0) {
1022 return NT_STATUS_RETRY;
1025 /* should not be reached */
1026 return NT_STATUS_INTERNAL_ERROR;
1030 * Only allow 5 outstanding trans requests. We're allocating memory, so
1031 * prevent a DoS.
1034 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1036 int count = 0;
1037 for (; list != NULL; list = list->next) {
1039 if (list->mid == mid) {
1040 return NT_STATUS_INVALID_PARAMETER;
1043 count += 1;
1045 if (count > 5) {
1046 return NT_STATUS_INSUFFICIENT_RESOURCES;
1049 return NT_STATUS_OK;
1053 These flags determine some of the permissions required to do an operation
1055 Note that I don't set NEED_WRITE on some write operations because they
1056 are used by some brain-dead clients when printing, and I don't want to
1057 force write permissions on print services.
1059 #define AS_USER (1<<0)
1060 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1061 #define TIME_INIT (1<<2)
1062 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1063 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1064 #define DO_CHDIR (1<<6)
1067 define a list of possible SMB messages and their corresponding
1068 functions. Any message that has a NULL function is unimplemented -
1069 please feel free to contribute implementations!
1071 static const struct smb_message_struct {
1072 const char *name;
1073 void (*fn)(struct smb_request *req);
1074 int flags;
1075 } smb_messages[256] = {
1077 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1078 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1079 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1080 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1081 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1082 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1083 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1084 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1085 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1086 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1087 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1088 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1089 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1090 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1091 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1092 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1093 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1094 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1095 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1096 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1097 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1098 /* 0x15 */ { NULL, NULL, 0 },
1099 /* 0x16 */ { NULL, NULL, 0 },
1100 /* 0x17 */ { NULL, NULL, 0 },
1101 /* 0x18 */ { NULL, NULL, 0 },
1102 /* 0x19 */ { NULL, NULL, 0 },
1103 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1104 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1105 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1106 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1107 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1108 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1109 /* 0x20 */ { "SMBwritec", NULL,0},
1110 /* 0x21 */ { NULL, NULL, 0 },
1111 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1112 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1113 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1114 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1115 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1116 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1117 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1118 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1119 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1120 /* 0x2b */ { "SMBecho",reply_echo,0},
1121 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1122 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1123 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1124 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1125 /* 0x30 */ { NULL, NULL, 0 },
1126 /* 0x31 */ { NULL, NULL, 0 },
1127 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1128 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1129 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1130 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1131 /* 0x36 */ { NULL, NULL, 0 },
1132 /* 0x37 */ { NULL, NULL, 0 },
1133 /* 0x38 */ { NULL, NULL, 0 },
1134 /* 0x39 */ { NULL, NULL, 0 },
1135 /* 0x3a */ { NULL, NULL, 0 },
1136 /* 0x3b */ { NULL, NULL, 0 },
1137 /* 0x3c */ { NULL, NULL, 0 },
1138 /* 0x3d */ { NULL, NULL, 0 },
1139 /* 0x3e */ { NULL, NULL, 0 },
1140 /* 0x3f */ { NULL, NULL, 0 },
1141 /* 0x40 */ { NULL, NULL, 0 },
1142 /* 0x41 */ { NULL, NULL, 0 },
1143 /* 0x42 */ { NULL, NULL, 0 },
1144 /* 0x43 */ { NULL, NULL, 0 },
1145 /* 0x44 */ { NULL, NULL, 0 },
1146 /* 0x45 */ { NULL, NULL, 0 },
1147 /* 0x46 */ { NULL, NULL, 0 },
1148 /* 0x47 */ { NULL, NULL, 0 },
1149 /* 0x48 */ { NULL, NULL, 0 },
1150 /* 0x49 */ { NULL, NULL, 0 },
1151 /* 0x4a */ { NULL, NULL, 0 },
1152 /* 0x4b */ { NULL, NULL, 0 },
1153 /* 0x4c */ { NULL, NULL, 0 },
1154 /* 0x4d */ { NULL, NULL, 0 },
1155 /* 0x4e */ { NULL, NULL, 0 },
1156 /* 0x4f */ { NULL, NULL, 0 },
1157 /* 0x50 */ { NULL, NULL, 0 },
1158 /* 0x51 */ { NULL, NULL, 0 },
1159 /* 0x52 */ { NULL, NULL, 0 },
1160 /* 0x53 */ { NULL, NULL, 0 },
1161 /* 0x54 */ { NULL, NULL, 0 },
1162 /* 0x55 */ { NULL, NULL, 0 },
1163 /* 0x56 */ { NULL, NULL, 0 },
1164 /* 0x57 */ { NULL, NULL, 0 },
1165 /* 0x58 */ { NULL, NULL, 0 },
1166 /* 0x59 */ { NULL, NULL, 0 },
1167 /* 0x5a */ { NULL, NULL, 0 },
1168 /* 0x5b */ { NULL, NULL, 0 },
1169 /* 0x5c */ { NULL, NULL, 0 },
1170 /* 0x5d */ { NULL, NULL, 0 },
1171 /* 0x5e */ { NULL, NULL, 0 },
1172 /* 0x5f */ { NULL, NULL, 0 },
1173 /* 0x60 */ { NULL, NULL, 0 },
1174 /* 0x61 */ { NULL, NULL, 0 },
1175 /* 0x62 */ { NULL, NULL, 0 },
1176 /* 0x63 */ { NULL, NULL, 0 },
1177 /* 0x64 */ { NULL, NULL, 0 },
1178 /* 0x65 */ { NULL, NULL, 0 },
1179 /* 0x66 */ { NULL, NULL, 0 },
1180 /* 0x67 */ { NULL, NULL, 0 },
1181 /* 0x68 */ { NULL, NULL, 0 },
1182 /* 0x69 */ { NULL, NULL, 0 },
1183 /* 0x6a */ { NULL, NULL, 0 },
1184 /* 0x6b */ { NULL, NULL, 0 },
1185 /* 0x6c */ { NULL, NULL, 0 },
1186 /* 0x6d */ { NULL, NULL, 0 },
1187 /* 0x6e */ { NULL, NULL, 0 },
1188 /* 0x6f */ { NULL, NULL, 0 },
1189 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1190 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1191 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1192 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1193 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1194 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1195 /* 0x76 */ { NULL, NULL, 0 },
1196 /* 0x77 */ { NULL, NULL, 0 },
1197 /* 0x78 */ { NULL, NULL, 0 },
1198 /* 0x79 */ { NULL, NULL, 0 },
1199 /* 0x7a */ { NULL, NULL, 0 },
1200 /* 0x7b */ { NULL, NULL, 0 },
1201 /* 0x7c */ { NULL, NULL, 0 },
1202 /* 0x7d */ { NULL, NULL, 0 },
1203 /* 0x7e */ { NULL, NULL, 0 },
1204 /* 0x7f */ { NULL, NULL, 0 },
1205 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1206 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1207 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1208 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1209 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1210 /* 0x85 */ { NULL, NULL, 0 },
1211 /* 0x86 */ { NULL, NULL, 0 },
1212 /* 0x87 */ { NULL, NULL, 0 },
1213 /* 0x88 */ { NULL, NULL, 0 },
1214 /* 0x89 */ { NULL, NULL, 0 },
1215 /* 0x8a */ { NULL, NULL, 0 },
1216 /* 0x8b */ { NULL, NULL, 0 },
1217 /* 0x8c */ { NULL, NULL, 0 },
1218 /* 0x8d */ { NULL, NULL, 0 },
1219 /* 0x8e */ { NULL, NULL, 0 },
1220 /* 0x8f */ { NULL, NULL, 0 },
1221 /* 0x90 */ { NULL, NULL, 0 },
1222 /* 0x91 */ { NULL, NULL, 0 },
1223 /* 0x92 */ { NULL, NULL, 0 },
1224 /* 0x93 */ { NULL, NULL, 0 },
1225 /* 0x94 */ { NULL, NULL, 0 },
1226 /* 0x95 */ { NULL, NULL, 0 },
1227 /* 0x96 */ { NULL, NULL, 0 },
1228 /* 0x97 */ { NULL, NULL, 0 },
1229 /* 0x98 */ { NULL, NULL, 0 },
1230 /* 0x99 */ { NULL, NULL, 0 },
1231 /* 0x9a */ { NULL, NULL, 0 },
1232 /* 0x9b */ { NULL, NULL, 0 },
1233 /* 0x9c */ { NULL, NULL, 0 },
1234 /* 0x9d */ { NULL, NULL, 0 },
1235 /* 0x9e */ { NULL, NULL, 0 },
1236 /* 0x9f */ { NULL, NULL, 0 },
1237 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1238 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1239 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1240 /* 0xa3 */ { NULL, NULL, 0 },
1241 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1242 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1243 /* 0xa6 */ { NULL, NULL, 0 },
1244 /* 0xa7 */ { NULL, NULL, 0 },
1245 /* 0xa8 */ { NULL, NULL, 0 },
1246 /* 0xa9 */ { NULL, NULL, 0 },
1247 /* 0xaa */ { NULL, NULL, 0 },
1248 /* 0xab */ { NULL, NULL, 0 },
1249 /* 0xac */ { NULL, NULL, 0 },
1250 /* 0xad */ { NULL, NULL, 0 },
1251 /* 0xae */ { NULL, NULL, 0 },
1252 /* 0xaf */ { NULL, NULL, 0 },
1253 /* 0xb0 */ { NULL, NULL, 0 },
1254 /* 0xb1 */ { NULL, NULL, 0 },
1255 /* 0xb2 */ { NULL, NULL, 0 },
1256 /* 0xb3 */ { NULL, NULL, 0 },
1257 /* 0xb4 */ { NULL, NULL, 0 },
1258 /* 0xb5 */ { NULL, NULL, 0 },
1259 /* 0xb6 */ { NULL, NULL, 0 },
1260 /* 0xb7 */ { NULL, NULL, 0 },
1261 /* 0xb8 */ { NULL, NULL, 0 },
1262 /* 0xb9 */ { NULL, NULL, 0 },
1263 /* 0xba */ { NULL, NULL, 0 },
1264 /* 0xbb */ { NULL, NULL, 0 },
1265 /* 0xbc */ { NULL, NULL, 0 },
1266 /* 0xbd */ { NULL, NULL, 0 },
1267 /* 0xbe */ { NULL, NULL, 0 },
1268 /* 0xbf */ { NULL, NULL, 0 },
1269 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1270 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1271 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1272 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1273 /* 0xc4 */ { NULL, NULL, 0 },
1274 /* 0xc5 */ { NULL, NULL, 0 },
1275 /* 0xc6 */ { NULL, NULL, 0 },
1276 /* 0xc7 */ { NULL, NULL, 0 },
1277 /* 0xc8 */ { NULL, NULL, 0 },
1278 /* 0xc9 */ { NULL, NULL, 0 },
1279 /* 0xca */ { NULL, NULL, 0 },
1280 /* 0xcb */ { NULL, NULL, 0 },
1281 /* 0xcc */ { NULL, NULL, 0 },
1282 /* 0xcd */ { NULL, NULL, 0 },
1283 /* 0xce */ { NULL, NULL, 0 },
1284 /* 0xcf */ { NULL, NULL, 0 },
1285 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1286 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1287 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1288 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1289 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1290 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1291 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1292 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1293 /* 0xd8 */ { NULL, NULL, 0 },
1294 /* 0xd9 */ { NULL, NULL, 0 },
1295 /* 0xda */ { NULL, NULL, 0 },
1296 /* 0xdb */ { NULL, NULL, 0 },
1297 /* 0xdc */ { NULL, NULL, 0 },
1298 /* 0xdd */ { NULL, NULL, 0 },
1299 /* 0xde */ { NULL, NULL, 0 },
1300 /* 0xdf */ { NULL, NULL, 0 },
1301 /* 0xe0 */ { NULL, NULL, 0 },
1302 /* 0xe1 */ { NULL, NULL, 0 },
1303 /* 0xe2 */ { NULL, NULL, 0 },
1304 /* 0xe3 */ { NULL, NULL, 0 },
1305 /* 0xe4 */ { NULL, NULL, 0 },
1306 /* 0xe5 */ { NULL, NULL, 0 },
1307 /* 0xe6 */ { NULL, NULL, 0 },
1308 /* 0xe7 */ { NULL, NULL, 0 },
1309 /* 0xe8 */ { NULL, NULL, 0 },
1310 /* 0xe9 */ { NULL, NULL, 0 },
1311 /* 0xea */ { NULL, NULL, 0 },
1312 /* 0xeb */ { NULL, NULL, 0 },
1313 /* 0xec */ { NULL, NULL, 0 },
1314 /* 0xed */ { NULL, NULL, 0 },
1315 /* 0xee */ { NULL, NULL, 0 },
1316 /* 0xef */ { NULL, NULL, 0 },
1317 /* 0xf0 */ { NULL, NULL, 0 },
1318 /* 0xf1 */ { NULL, NULL, 0 },
1319 /* 0xf2 */ { NULL, NULL, 0 },
1320 /* 0xf3 */ { NULL, NULL, 0 },
1321 /* 0xf4 */ { NULL, NULL, 0 },
1322 /* 0xf5 */ { NULL, NULL, 0 },
1323 /* 0xf6 */ { NULL, NULL, 0 },
1324 /* 0xf7 */ { NULL, NULL, 0 },
1325 /* 0xf8 */ { NULL, NULL, 0 },
1326 /* 0xf9 */ { NULL, NULL, 0 },
1327 /* 0xfa */ { NULL, NULL, 0 },
1328 /* 0xfb */ { NULL, NULL, 0 },
1329 /* 0xfc */ { NULL, NULL, 0 },
1330 /* 0xfd */ { NULL, NULL, 0 },
1331 /* 0xfe */ { NULL, NULL, 0 },
1332 /* 0xff */ { NULL, NULL, 0 }
1336 /*******************************************************************
1337 allocate and initialize a reply packet
1338 ********************************************************************/
1340 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1341 const char *inbuf, char **outbuf, uint8_t num_words,
1342 uint32_t num_bytes)
1345 * Protect against integer wrap
1347 if ((num_bytes > 0xffffff)
1348 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1349 char *msg;
1350 if (asprintf(&msg, "num_bytes too large: %u",
1351 (unsigned)num_bytes) == -1) {
1352 msg = CONST_DISCARD(char *, "num_bytes too large");
1354 smb_panic(msg);
1357 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1358 smb_size + num_words*2 + num_bytes);
1359 if (*outbuf == NULL) {
1360 return false;
1363 construct_reply_common(req, inbuf, *outbuf);
1364 srv_set_message(*outbuf, num_words, num_bytes, false);
1366 * Zero out the word area, the caller has to take care of the bcc area
1367 * himself
1369 if (num_words != 0) {
1370 memset(*outbuf + smb_vwv0, 0, num_words*2);
1373 return true;
1376 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1378 char *outbuf;
1379 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1380 num_bytes)) {
1381 smb_panic("could not allocate output buffer\n");
1383 req->outbuf = (uint8_t *)outbuf;
1387 /*******************************************************************
1388 Dump a packet to a file.
1389 ********************************************************************/
1391 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1393 int fd, i;
1394 char *fname = NULL;
1395 if (DEBUGLEVEL < 50) {
1396 return;
1399 if (len < 4) len = smb_len(data)+4;
1400 for (i=1;i<100;i++) {
1401 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1402 type ? "req" : "resp") == -1) {
1403 return;
1405 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1406 if (fd != -1 || errno != EEXIST) break;
1408 if (fd != -1) {
1409 ssize_t ret = write(fd, data, len);
1410 if (ret != len)
1411 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1412 close(fd);
1413 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1415 SAFE_FREE(fname);
1418 /****************************************************************************
1419 Prepare everything for calling the actual request function, and potentially
1420 call the request function via the "new" interface.
1422 Return False if the "legacy" function needs to be called, everything is
1423 prepared.
1425 Return True if we're done.
1427 I know this API sucks, but it is the one with the least code change I could
1428 find.
1429 ****************************************************************************/
1431 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1433 int flags;
1434 uint16 session_tag;
1435 connection_struct *conn = NULL;
1436 struct smbd_server_connection *sconn = req->sconn;
1438 errno = 0;
1440 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1441 * so subtract 4 from it. */
1442 if (!valid_smb_header(req->inbuf)
1443 || (size < (smb_size - 4))) {
1444 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1445 smb_len(req->inbuf)));
1446 exit_server_cleanly("Non-SMB packet");
1449 if (smb_messages[type].fn == NULL) {
1450 DEBUG(0,("Unknown message type %d!\n",type));
1451 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1452 reply_unknown_new(req, type);
1453 return NULL;
1456 flags = smb_messages[type].flags;
1458 /* In share mode security we must ignore the vuid. */
1459 session_tag = (lp_security() == SEC_SHARE)
1460 ? UID_FIELD_INVALID : req->vuid;
1461 conn = req->conn;
1463 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1464 (int)sys_getpid(), (unsigned long)conn));
1466 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1468 /* Ensure this value is replaced in the incoming packet. */
1469 SSVAL(req->inbuf,smb_uid,session_tag);
1472 * Ensure the correct username is in current_user_info. This is a
1473 * really ugly bugfix for problems with multiple session_setup_and_X's
1474 * being done and allowing %U and %G substitutions to work correctly.
1475 * There is a reason this code is done here, don't move it unless you
1476 * know what you're doing... :-).
1477 * JRA.
1480 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1481 user_struct *vuser = NULL;
1483 sconn->smb1.sessions.last_session_tag = session_tag;
1484 if(session_tag != UID_FIELD_INVALID) {
1485 vuser = get_valid_user_struct(sconn, session_tag);
1486 if (vuser) {
1487 set_current_user_info(
1488 vuser->session_info->sanitized_username,
1489 vuser->session_info->unix_name,
1490 vuser->session_info->info3->base.domain.string);
1495 /* Does this call need to be run as the connected user? */
1496 if (flags & AS_USER) {
1498 /* Does this call need a valid tree connection? */
1499 if (!conn) {
1501 * Amazingly, the error code depends on the command
1502 * (from Samba4).
1504 if (type == SMBntcreateX) {
1505 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1506 } else {
1507 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1509 return NULL;
1512 if (!change_to_user(conn,session_tag)) {
1513 DEBUG(0, ("Error: Could not change to user. Removing "
1514 "deferred open, mid=%llu.\n",
1515 (unsigned long long)req->mid));
1516 reply_force_doserror(req, ERRSRV, ERRbaduid);
1517 return conn;
1520 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1522 /* Does it need write permission? */
1523 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1524 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1525 return conn;
1528 /* IPC services are limited */
1529 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1530 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1531 return conn;
1533 } else {
1534 /* This call needs to be run as root */
1535 change_to_root_user();
1538 /* load service specific parameters */
1539 if (conn) {
1540 if (req->encrypted) {
1541 conn->encrypted_tid = true;
1542 /* encrypted required from now on. */
1543 conn->encrypt_level = Required;
1544 } else if (ENCRYPTION_REQUIRED(conn)) {
1545 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1546 exit_server_cleanly("encryption required "
1547 "on connection");
1548 return conn;
1552 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1553 (flags & (AS_USER|DO_CHDIR)
1554 ?True:False))) {
1555 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1556 return conn;
1558 conn->num_smb_operations++;
1561 /* does this protocol need to be run as guest? */
1562 if ((flags & AS_GUEST)
1563 && (!change_to_guest() ||
1564 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1565 sconn->client_id.name,
1566 sconn->client_id.addr))) {
1567 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1568 return conn;
1571 smb_messages[type].fn(req);
1572 return req->conn;
1575 /****************************************************************************
1576 Construct a reply to the incoming packet.
1577 ****************************************************************************/
1579 static void construct_reply(struct smbd_server_connection *sconn,
1580 char *inbuf, int size, size_t unread_bytes,
1581 uint32_t seqnum, bool encrypted,
1582 struct smb_perfcount_data *deferred_pcd)
1584 connection_struct *conn;
1585 struct smb_request *req;
1587 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1588 smb_panic("could not allocate smb_request");
1591 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1592 encrypted, seqnum)) {
1593 exit_server_cleanly("Invalid SMB request");
1596 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1598 /* we popped this message off the queue - keep original perf data */
1599 if (deferred_pcd)
1600 req->pcd = *deferred_pcd;
1601 else {
1602 SMB_PERFCOUNT_START(&req->pcd);
1603 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1604 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1607 conn = switch_message(req->cmd, req, size);
1609 if (req->unread_bytes) {
1610 /* writeX failed. drain socket. */
1611 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1612 req->unread_bytes) {
1613 smb_panic("failed to drain pending bytes");
1615 req->unread_bytes = 0;
1618 if (req->done) {
1619 TALLOC_FREE(req);
1620 return;
1623 if (req->outbuf == NULL) {
1624 return;
1627 if (CVAL(req->outbuf,0) == 0) {
1628 show_msg((char *)req->outbuf);
1631 if (!srv_send_smb(req->sconn,
1632 (char *)req->outbuf,
1633 true, req->seqnum+1,
1634 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1635 &req->pcd)) {
1636 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1639 TALLOC_FREE(req);
1641 return;
1644 /****************************************************************************
1645 Process an smb from the client
1646 ****************************************************************************/
1647 static void process_smb(struct smbd_server_connection *sconn,
1648 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1649 uint32_t seqnum, bool encrypted,
1650 struct smb_perfcount_data *deferred_pcd)
1652 int msg_type = CVAL(inbuf,0);
1654 DO_PROFILE_INC(smb_count);
1656 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1657 smb_len(inbuf) ) );
1658 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1659 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1661 if (msg_type != 0) {
1663 * NetBIOS session request, keepalive, etc.
1665 reply_special(sconn, (char *)inbuf, nread);
1666 goto done;
1669 if (sconn->using_smb2) {
1670 /* At this point we're not really using smb2,
1671 * we make the decision here.. */
1672 if (smbd_is_smb2_header(inbuf, nread)) {
1673 smbd_smb2_first_negprot(sconn, inbuf, nread);
1674 return;
1675 } else if (nread >= smb_size && valid_smb_header(inbuf)
1676 && CVAL(inbuf, smb_com) != 0x72) {
1677 /* This is a non-negprot SMB1 packet.
1678 Disable SMB2 from now on. */
1679 sconn->using_smb2 = false;
1683 show_msg((char *)inbuf);
1685 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1686 encrypted, deferred_pcd);
1687 sconn->trans_num++;
1689 done:
1690 sconn->smb1.num_requests++;
1692 /* The timeout_processing function isn't run nearly
1693 often enough to implement 'max log size' without
1694 overrunning the size of the file by many megabytes.
1695 This is especially true if we are running at debug
1696 level 10. Checking every 50 SMBs is a nice
1697 tradeoff of performance vs log file size overrun. */
1699 if ((sconn->smb1.num_requests % 50) == 0 &&
1700 need_to_check_log_size()) {
1701 change_to_root_user();
1702 check_log_size();
1706 /****************************************************************************
1707 Return a string containing the function name of a SMB command.
1708 ****************************************************************************/
1710 const char *smb_fn_name(int type)
1712 const char *unknown_name = "SMBunknown";
1714 if (smb_messages[type].name == NULL)
1715 return(unknown_name);
1717 return(smb_messages[type].name);
1720 /****************************************************************************
1721 Helper functions for contruct_reply.
1722 ****************************************************************************/
1724 void add_to_common_flags2(uint32 v)
1726 common_flags2 |= v;
1729 void remove_from_common_flags2(uint32 v)
1731 common_flags2 &= ~v;
1734 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1735 char *outbuf)
1737 srv_set_message(outbuf,0,0,false);
1739 SCVAL(outbuf, smb_com, req->cmd);
1740 SIVAL(outbuf,smb_rcls,0);
1741 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1742 SSVAL(outbuf,smb_flg2,
1743 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1744 common_flags2);
1745 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1747 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1748 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1749 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1750 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1753 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1755 construct_reply_common(req, (char *)req->inbuf, outbuf);
1759 * How many bytes have we already accumulated up to the current wct field
1760 * offset?
1763 size_t req_wct_ofs(struct smb_request *req)
1765 size_t buf_size;
1767 if (req->chain_outbuf == NULL) {
1768 return smb_wct - 4;
1770 buf_size = talloc_get_size(req->chain_outbuf);
1771 if ((buf_size % 4) != 0) {
1772 buf_size += (4 - (buf_size % 4));
1774 return buf_size - 4;
1778 * Hack around reply_nterror & friends not being aware of chained requests,
1779 * generating illegal (i.e. wct==0) chain replies.
1782 static void fixup_chain_error_packet(struct smb_request *req)
1784 uint8_t *outbuf = req->outbuf;
1785 req->outbuf = NULL;
1786 reply_outbuf(req, 2, 0);
1787 memcpy(req->outbuf, outbuf, smb_wct);
1788 TALLOC_FREE(outbuf);
1789 SCVAL(req->outbuf, smb_vwv0, 0xff);
1793 * @brief Find the smb_cmd offset of the last command pushed
1794 * @param[in] buf The buffer we're building up
1795 * @retval Where can we put our next andx cmd?
1797 * While chaining requests, the "next" request we're looking at needs to put
1798 * its SMB_Command before the data the previous request already built up added
1799 * to the chain. Find the offset to the place where we have to put our cmd.
1802 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1804 uint8_t cmd;
1805 size_t ofs;
1807 cmd = CVAL(buf, smb_com);
1809 SMB_ASSERT(is_andx_req(cmd));
1811 ofs = smb_vwv0;
1813 while (CVAL(buf, ofs) != 0xff) {
1815 if (!is_andx_req(CVAL(buf, ofs))) {
1816 return false;
1820 * ofs is from start of smb header, so add the 4 length
1821 * bytes. The next cmd is right after the wct field.
1823 ofs = SVAL(buf, ofs+2) + 4 + 1;
1825 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1828 *pofs = ofs;
1829 return true;
1833 * @brief Do the smb chaining at a buffer level
1834 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1835 * @param[in] smb_command The command that we want to issue
1836 * @param[in] wct How many words?
1837 * @param[in] vwv The words, already in network order
1838 * @param[in] bytes_alignment How shall we align "bytes"?
1839 * @param[in] num_bytes How many bytes?
1840 * @param[in] bytes The data the request ships
1842 * smb_splice_chain() adds the vwv and bytes to the request already present in
1843 * *poutbuf.
1846 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1847 uint8_t wct, const uint16_t *vwv,
1848 size_t bytes_alignment,
1849 uint32_t num_bytes, const uint8_t *bytes)
1851 uint8_t *outbuf;
1852 size_t old_size, new_size;
1853 size_t ofs;
1854 size_t chain_padding = 0;
1855 size_t bytes_padding = 0;
1856 bool first_request;
1858 old_size = talloc_get_size(*poutbuf);
1861 * old_size == smb_wct means we're pushing the first request in for
1862 * libsmb/
1865 first_request = (old_size == smb_wct);
1867 if (!first_request && ((old_size % 4) != 0)) {
1869 * Align the wct field of subsequent requests to a 4-byte
1870 * boundary
1872 chain_padding = 4 - (old_size % 4);
1876 * After the old request comes the new wct field (1 byte), the vwv's
1877 * and the num_bytes field. After at we might need to align the bytes
1878 * given to us to "bytes_alignment", increasing the num_bytes value.
1881 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1883 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1884 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1887 new_size += bytes_padding + num_bytes;
1889 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1890 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1891 (unsigned)new_size));
1892 return false;
1895 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1896 if (outbuf == NULL) {
1897 DEBUG(0, ("talloc failed\n"));
1898 return false;
1900 *poutbuf = outbuf;
1902 if (first_request) {
1903 SCVAL(outbuf, smb_com, smb_command);
1904 } else {
1905 size_t andx_cmd_ofs;
1907 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1908 DEBUG(1, ("invalid command chain\n"));
1909 *poutbuf = TALLOC_REALLOC_ARRAY(
1910 NULL, *poutbuf, uint8_t, old_size);
1911 return false;
1914 if (chain_padding != 0) {
1915 memset(outbuf + old_size, 0, chain_padding);
1916 old_size += chain_padding;
1919 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1920 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1923 ofs = old_size;
1926 * Push the chained request:
1928 * wct field
1931 SCVAL(outbuf, ofs, wct);
1932 ofs += 1;
1935 * vwv array
1938 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1939 ofs += sizeof(uint16_t) * wct;
1942 * bcc (byte count)
1945 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1946 ofs += sizeof(uint16_t);
1949 * padding
1952 if (bytes_padding != 0) {
1953 memset(outbuf + ofs, 0, bytes_padding);
1954 ofs += bytes_padding;
1958 * The bytes field
1961 memcpy(outbuf + ofs, bytes, num_bytes);
1963 return true;
1966 /****************************************************************************
1967 Construct a chained reply and add it to the already made reply
1968 ****************************************************************************/
1970 void chain_reply(struct smb_request *req)
1972 size_t smblen = smb_len(req->inbuf);
1973 size_t already_used, length_needed;
1974 uint8_t chain_cmd;
1975 uint32_t chain_offset; /* uint32_t to avoid overflow */
1977 uint8_t wct;
1978 uint16_t *vwv;
1979 uint16_t buflen;
1980 uint8_t *buf;
1982 if (IVAL(req->outbuf, smb_rcls) != 0) {
1983 fixup_chain_error_packet(req);
1987 * Any of the AndX requests and replies have at least a wct of
1988 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1989 * beginning of the SMB header to the next wct field.
1991 * None of the AndX requests put anything valuable in vwv[0] and [1],
1992 * so we can overwrite it here to form the chain.
1995 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1996 if (req->chain_outbuf == NULL) {
1997 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1998 req, req->outbuf, uint8_t,
1999 smb_len(req->outbuf) + 4);
2000 if (req->chain_outbuf == NULL) {
2001 smb_panic("talloc failed");
2004 req->outbuf = NULL;
2005 goto error;
2009 * Here we assume that this is the end of the chain. For that we need
2010 * to set "next command" to 0xff and the offset to 0. If we later find
2011 * more commands in the chain, this will be overwritten again.
2014 SCVAL(req->outbuf, smb_vwv0, 0xff);
2015 SCVAL(req->outbuf, smb_vwv0+1, 0);
2016 SSVAL(req->outbuf, smb_vwv1, 0);
2018 if (req->chain_outbuf == NULL) {
2020 * In req->chain_outbuf we collect all the replies. Start the
2021 * chain by copying in the first reply.
2023 * We do the realloc because later on we depend on
2024 * talloc_get_size to determine the length of
2025 * chain_outbuf. The reply_xxx routines might have
2026 * over-allocated (reply_pipe_read_and_X used to be such an
2027 * example).
2029 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2030 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2031 if (req->chain_outbuf == NULL) {
2032 smb_panic("talloc failed");
2034 req->outbuf = NULL;
2035 } else {
2037 * Update smb headers where subsequent chained commands
2038 * may have updated them.
2040 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2041 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2043 if (!smb_splice_chain(&req->chain_outbuf,
2044 CVAL(req->outbuf, smb_com),
2045 CVAL(req->outbuf, smb_wct),
2046 (uint16_t *)(req->outbuf + smb_vwv),
2047 0, smb_buflen(req->outbuf),
2048 (uint8_t *)smb_buf(req->outbuf))) {
2049 goto error;
2051 TALLOC_FREE(req->outbuf);
2055 * We use the old request's vwv field to grab the next chained command
2056 * and offset into the chained fields.
2059 chain_cmd = CVAL(req->vwv+0, 0);
2060 chain_offset = SVAL(req->vwv+1, 0);
2062 if (chain_cmd == 0xff) {
2064 * End of chain, no more requests from the client. So ship the
2065 * replies.
2067 smb_setlen((char *)(req->chain_outbuf),
2068 talloc_get_size(req->chain_outbuf) - 4);
2070 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2071 true, req->seqnum+1,
2072 IS_CONN_ENCRYPTED(req->conn)
2073 ||req->encrypted,
2074 &req->pcd)) {
2075 exit_server_cleanly("chain_reply: srv_send_smb "
2076 "failed.");
2078 TALLOC_FREE(req->chain_outbuf);
2079 req->done = true;
2080 return;
2083 /* add a new perfcounter for this element of chain */
2084 SMB_PERFCOUNT_ADD(&req->pcd);
2085 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2086 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2089 * Check if the client tries to fool us. The request so far uses the
2090 * space to the end of the byte buffer in the request just
2091 * processed. The chain_offset can't point into that area. If that was
2092 * the case, we could end up with an endless processing of the chain,
2093 * we would always handle the same request.
2096 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2097 if (chain_offset < already_used) {
2098 goto error;
2102 * Next check: Make sure the chain offset does not point beyond the
2103 * overall smb request length.
2106 length_needed = chain_offset+1; /* wct */
2107 if (length_needed > smblen) {
2108 goto error;
2112 * Now comes the pointer magic. Goal here is to set up req->vwv and
2113 * req->buf correctly again to be able to call the subsequent
2114 * switch_message(). The chain offset (the former vwv[1]) points at
2115 * the new wct field.
2118 wct = CVAL(smb_base(req->inbuf), chain_offset);
2121 * Next consistency check: Make the new vwv array fits in the overall
2122 * smb request.
2125 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2126 if (length_needed > smblen) {
2127 goto error;
2129 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2132 * Now grab the new byte buffer....
2135 buflen = SVAL(vwv+wct, 0);
2138 * .. and check that it fits.
2141 length_needed += buflen;
2142 if (length_needed > smblen) {
2143 goto error;
2145 buf = (uint8_t *)(vwv+wct+1);
2147 req->cmd = chain_cmd;
2148 req->wct = wct;
2149 req->vwv = vwv;
2150 req->buflen = buflen;
2151 req->buf = buf;
2153 switch_message(chain_cmd, req, smblen);
2155 if (req->outbuf == NULL) {
2157 * This happens if the chained command has suspended itself or
2158 * if it has called srv_send_smb() itself.
2160 return;
2164 * We end up here if the chained command was not itself chained or
2165 * suspended, but for example a close() command. We now need to splice
2166 * the chained commands' outbuf into the already built up chain_outbuf
2167 * and ship the result.
2169 goto done;
2171 error:
2173 * We end up here if there's any error in the chain syntax. Report a
2174 * DOS error, just like Windows does.
2176 reply_force_doserror(req, ERRSRV, ERRerror);
2177 fixup_chain_error_packet(req);
2179 done:
2181 * This scary statement intends to set the
2182 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2183 * to the value req->outbuf carries
2185 SSVAL(req->chain_outbuf, smb_flg2,
2186 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2187 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2190 * Transfer the error codes from the subrequest to the main one
2192 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2193 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2195 if (!smb_splice_chain(&req->chain_outbuf,
2196 CVAL(req->outbuf, smb_com),
2197 CVAL(req->outbuf, smb_wct),
2198 (uint16_t *)(req->outbuf + smb_vwv),
2199 0, smb_buflen(req->outbuf),
2200 (uint8_t *)smb_buf(req->outbuf))) {
2201 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2203 TALLOC_FREE(req->outbuf);
2205 smb_setlen((char *)(req->chain_outbuf),
2206 talloc_get_size(req->chain_outbuf) - 4);
2208 show_msg((char *)(req->chain_outbuf));
2210 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2211 true, req->seqnum+1,
2212 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2213 &req->pcd)) {
2214 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2216 TALLOC_FREE(req->chain_outbuf);
2217 req->done = true;
2220 /****************************************************************************
2221 Check if services need reloading.
2222 ****************************************************************************/
2224 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2227 if (last_smb_conf_reload_time == 0) {
2228 last_smb_conf_reload_time = t;
2231 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2232 reload_services(sconn->msg_ctx, sconn->sock, True);
2233 last_smb_conf_reload_time = t;
2237 static bool fd_is_readable(int fd)
2239 int ret, revents;
2241 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2243 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2247 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2249 /* TODO: make write nonblocking */
2252 static void smbd_server_connection_read_handler(
2253 struct smbd_server_connection *conn, int fd)
2255 uint8_t *inbuf = NULL;
2256 size_t inbuf_len = 0;
2257 size_t unread_bytes = 0;
2258 bool encrypted = false;
2259 TALLOC_CTX *mem_ctx = talloc_tos();
2260 NTSTATUS status;
2261 uint32_t seqnum;
2263 bool from_client = (conn->sock == fd);
2265 if (from_client) {
2266 smbd_lock_socket(conn);
2268 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2269 DEBUG(10,("the echo listener was faster\n"));
2270 smbd_unlock_socket(conn);
2271 return;
2274 /* TODO: make this completely nonblocking */
2275 status = receive_smb_talloc(mem_ctx, conn, fd,
2276 (char **)(void *)&inbuf,
2277 0, /* timeout */
2278 &unread_bytes,
2279 &encrypted,
2280 &inbuf_len, &seqnum,
2281 false /* trusted channel */);
2282 smbd_unlock_socket(conn);
2283 } else {
2284 /* TODO: make this completely nonblocking */
2285 status = receive_smb_talloc(mem_ctx, conn, fd,
2286 (char **)(void *)&inbuf,
2287 0, /* timeout */
2288 &unread_bytes,
2289 &encrypted,
2290 &inbuf_len, &seqnum,
2291 true /* trusted channel */);
2294 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2295 goto process;
2297 if (NT_STATUS_IS_ERR(status)) {
2298 exit_server_cleanly("failed to receive smb request");
2300 if (!NT_STATUS_IS_OK(status)) {
2301 return;
2304 process:
2305 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2306 seqnum, encrypted, NULL);
2309 static void smbd_server_connection_handler(struct event_context *ev,
2310 struct fd_event *fde,
2311 uint16_t flags,
2312 void *private_data)
2314 struct smbd_server_connection *conn = talloc_get_type(private_data,
2315 struct smbd_server_connection);
2317 if (flags & EVENT_FD_WRITE) {
2318 smbd_server_connection_write_handler(conn);
2319 return;
2321 if (flags & EVENT_FD_READ) {
2322 smbd_server_connection_read_handler(conn, conn->sock);
2323 return;
2327 static void smbd_server_echo_handler(struct event_context *ev,
2328 struct fd_event *fde,
2329 uint16_t flags,
2330 void *private_data)
2332 struct smbd_server_connection *conn = talloc_get_type(private_data,
2333 struct smbd_server_connection);
2335 if (flags & EVENT_FD_WRITE) {
2336 smbd_server_connection_write_handler(conn);
2337 return;
2339 if (flags & EVENT_FD_READ) {
2340 smbd_server_connection_read_handler(
2341 conn, conn->smb1.echo_handler.trusted_fd);
2342 return;
2346 /****************************************************************************
2347 received when we should release a specific IP
2348 ****************************************************************************/
2349 static void release_ip(const char *ip, void *priv)
2351 const char *addr = (const char *)priv;
2352 const char *p = addr;
2354 if (strncmp("::ffff:", addr, 7) == 0) {
2355 p = addr + 7;
2358 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2359 /* we can't afford to do a clean exit - that involves
2360 database writes, which would potentially mean we
2361 are still running after the failover has finished -
2362 we have to get rid of this process ID straight
2363 away */
2364 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2365 ip));
2366 /* note we must exit with non-zero status so the unclean handler gets
2367 called in the parent, so that the brl database is tickled */
2368 _exit(1);
2372 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2373 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2375 struct smbd_server_connection *sconn = talloc_get_type_abort(
2376 private_data, struct smbd_server_connection);
2378 release_ip((char *)data->data, sconn->client_id.addr);
2381 #ifdef CLUSTER_SUPPORT
2382 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2383 struct sockaddr_storage *client)
2385 socklen_t length;
2386 length = sizeof(*server);
2387 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2388 return -1;
2390 length = sizeof(*client);
2391 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2392 return -1;
2394 return 0;
2396 #endif
2399 * Send keepalive packets to our client
2401 static bool keepalive_fn(const struct timeval *now, void *private_data)
2403 struct smbd_server_connection *sconn = smbd_server_conn;
2404 bool ret;
2406 if (sconn->using_smb2) {
2407 /* Don't do keepalives on an SMB2 connection. */
2408 return false;
2411 smbd_lock_socket(smbd_server_conn);
2412 ret = send_keepalive(sconn->sock);
2413 smbd_unlock_socket(smbd_server_conn);
2415 if (!ret) {
2416 char addr[INET6_ADDRSTRLEN];
2418 * Try and give an error message saying what
2419 * client failed.
2421 DEBUG(0, ("send_keepalive failed for client %s. "
2422 "Error %s - exiting\n",
2423 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2424 strerror(errno)));
2425 return False;
2427 return True;
2431 * Do the recurring check if we're idle
2433 static bool deadtime_fn(const struct timeval *now, void *private_data)
2435 struct smbd_server_connection *sconn =
2436 (struct smbd_server_connection *)private_data;
2438 if ((conn_num_open(sconn) == 0)
2439 || (conn_idle_all(sconn, now->tv_sec))) {
2440 DEBUG( 2, ( "Closing idle connection\n" ) );
2441 messaging_send(sconn->msg_ctx,
2442 messaging_server_id(sconn->msg_ctx),
2443 MSG_SHUTDOWN, &data_blob_null);
2444 return False;
2447 return True;
2451 * Do the recurring log file and smb.conf reload checks.
2454 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2456 struct smbd_server_connection *sconn = talloc_get_type_abort(
2457 private_data, struct smbd_server_connection);
2459 DEBUG(5, ("housekeeping\n"));
2461 change_to_root_user();
2463 /* update printer queue caches if necessary */
2464 update_monitored_printq_cache(sconn->msg_ctx);
2466 /* check if we need to reload services */
2467 check_reload(sconn, time_mono(NULL));
2469 /* Change machine password if neccessary. */
2470 attempt_machine_password_change();
2473 * Force a log file check.
2475 force_check_log_size();
2476 check_log_size();
2477 return true;
2480 static int create_unlink_tmp(const char *dir)
2482 char *fname;
2483 int fd;
2485 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2486 if (fname == NULL) {
2487 errno = ENOMEM;
2488 return -1;
2490 fd = mkstemp(fname);
2491 if (fd == -1) {
2492 TALLOC_FREE(fname);
2493 return -1;
2495 if (unlink(fname) == -1) {
2496 int sys_errno = errno;
2497 close(fd);
2498 TALLOC_FREE(fname);
2499 errno = sys_errno;
2500 return -1;
2502 TALLOC_FREE(fname);
2503 return fd;
2506 struct smbd_echo_state {
2507 struct tevent_context *ev;
2508 struct iovec *pending;
2509 struct smbd_server_connection *sconn;
2510 int parent_pipe;
2512 struct tevent_fd *parent_fde;
2514 struct tevent_fd *read_fde;
2515 struct tevent_req *write_req;
2518 static void smbd_echo_writer_done(struct tevent_req *req);
2520 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2522 int num_pending;
2524 if (state->write_req != NULL) {
2525 return;
2528 num_pending = talloc_array_length(state->pending);
2529 if (num_pending == 0) {
2530 return;
2533 state->write_req = writev_send(state, state->ev, NULL,
2534 state->parent_pipe, false,
2535 state->pending, num_pending);
2536 if (state->write_req == NULL) {
2537 DEBUG(1, ("writev_send failed\n"));
2538 exit(1);
2541 talloc_steal(state->write_req, state->pending);
2542 state->pending = NULL;
2544 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2545 state);
2548 static void smbd_echo_writer_done(struct tevent_req *req)
2550 struct smbd_echo_state *state = tevent_req_callback_data(
2551 req, struct smbd_echo_state);
2552 ssize_t written;
2553 int err;
2555 written = writev_recv(req, &err);
2556 TALLOC_FREE(req);
2557 state->write_req = NULL;
2558 if (written == -1) {
2559 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2560 exit(1);
2562 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2563 smbd_echo_activate_writer(state);
2566 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2567 uint32_t seqnum)
2569 struct smb_request req;
2570 uint16_t num_replies;
2571 size_t out_len;
2572 char *outbuf;
2573 bool ok;
2575 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2576 DEBUG(10, ("Got netbios keepalive\n"));
2578 * Just swallow it
2580 return true;
2583 if (inbuf_len < smb_size) {
2584 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2585 return false;
2587 if (!valid_smb_header(inbuf)) {
2588 DEBUG(10, ("Got invalid SMB header\n"));
2589 return false;
2592 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2593 seqnum)) {
2594 return false;
2596 req.inbuf = inbuf;
2598 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2599 smb_messages[req.cmd].name
2600 ? smb_messages[req.cmd].name : "unknown"));
2602 if (req.cmd != SMBecho) {
2603 return false;
2605 if (req.wct < 1) {
2606 return false;
2609 num_replies = SVAL(req.vwv+0, 0);
2610 if (num_replies != 1) {
2611 /* Not a Windows "Hey, you're still there?" request */
2612 return false;
2615 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2616 1, req.buflen)) {
2617 DEBUG(10, ("create_outbuf failed\n"));
2618 return false;
2620 req.outbuf = (uint8_t *)outbuf;
2622 SSVAL(req.outbuf, smb_vwv0, num_replies);
2624 if (req.buflen > 0) {
2625 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2628 out_len = smb_len(req.outbuf) + 4;
2630 ok = srv_send_smb(req.sconn,
2631 (char *)outbuf,
2632 true, seqnum+1,
2633 false, &req.pcd);
2634 TALLOC_FREE(outbuf);
2635 if (!ok) {
2636 exit(1);
2639 return true;
2642 static void smbd_echo_exit(struct tevent_context *ev,
2643 struct tevent_fd *fde, uint16_t flags,
2644 void *private_data)
2646 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2647 exit(0);
2650 static void smbd_echo_reader(struct tevent_context *ev,
2651 struct tevent_fd *fde, uint16_t flags,
2652 void *private_data)
2654 struct smbd_echo_state *state = talloc_get_type_abort(
2655 private_data, struct smbd_echo_state);
2656 struct smbd_server_connection *sconn = state->sconn;
2657 size_t unread, num_pending;
2658 NTSTATUS status;
2659 struct iovec *tmp;
2660 size_t iov_len;
2661 uint32_t seqnum = 0;
2662 bool reply;
2663 bool ok;
2664 bool encrypted = false;
2666 smb_msleep(1000);
2668 ok = smbd_lock_socket_internal(sconn);
2669 if (!ok) {
2670 DEBUG(0, ("%s: failed to lock socket\n",
2671 __location__));
2672 exit(1);
2675 if (!fd_is_readable(sconn->sock)) {
2676 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2677 (int)sys_getpid()));
2678 ok = smbd_unlock_socket_internal(sconn);
2679 if (!ok) {
2680 DEBUG(1, ("%s: failed to unlock socket in\n",
2681 __location__));
2682 exit(1);
2684 return;
2687 num_pending = talloc_array_length(state->pending);
2688 tmp = talloc_realloc(state, state->pending, struct iovec,
2689 num_pending+1);
2690 if (tmp == NULL) {
2691 DEBUG(1, ("talloc_realloc failed\n"));
2692 exit(1);
2694 state->pending = tmp;
2696 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2698 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2699 (char **)(void *)&state->pending[num_pending].iov_base,
2700 0 /* timeout */,
2701 &unread,
2702 &encrypted,
2703 &iov_len,
2704 &seqnum,
2705 false /* trusted_channel*/);
2706 if (!NT_STATUS_IS_OK(status)) {
2707 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2708 (int)sys_getpid(), nt_errstr(status)));
2709 exit(1);
2711 state->pending[num_pending].iov_len = iov_len;
2713 ok = smbd_unlock_socket_internal(sconn);
2714 if (!ok) {
2715 DEBUG(1, ("%s: failed to unlock socket in\n",
2716 __location__));
2717 exit(1);
2720 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2721 state->pending[num_pending].iov_len,
2722 seqnum);
2723 if (reply) {
2724 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2725 /* no check, shrinking by some bytes does not fail */
2726 state->pending = talloc_realloc(state, state->pending,
2727 struct iovec,
2728 num_pending);
2729 return;
2732 if (state->pending[num_pending].iov_len >= smb_size) {
2734 * place the seqnum in the packet so that the main process
2735 * can reply with signing
2737 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2738 smb_ss_field, seqnum);
2739 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2740 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2743 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2744 smbd_echo_activate_writer(state);
2747 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2748 int parent_pipe)
2750 struct smbd_echo_state *state;
2752 state = talloc_zero(sconn, struct smbd_echo_state);
2753 if (state == NULL) {
2754 DEBUG(1, ("talloc failed\n"));
2755 return;
2757 state->sconn = sconn;
2758 state->parent_pipe = parent_pipe;
2759 state->ev = s3_tevent_context_init(state);
2760 if (state->ev == NULL) {
2761 DEBUG(1, ("tevent_context_init failed\n"));
2762 TALLOC_FREE(state);
2763 return;
2765 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2766 TEVENT_FD_READ, smbd_echo_exit,
2767 state);
2768 if (state->parent_fde == NULL) {
2769 DEBUG(1, ("tevent_add_fd failed\n"));
2770 TALLOC_FREE(state);
2771 return;
2773 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2774 TEVENT_FD_READ, smbd_echo_reader,
2775 state);
2776 if (state->read_fde == NULL) {
2777 DEBUG(1, ("tevent_add_fd failed\n"));
2778 TALLOC_FREE(state);
2779 return;
2782 while (true) {
2783 if (tevent_loop_once(state->ev) == -1) {
2784 DEBUG(1, ("tevent_loop_once failed: %s\n",
2785 strerror(errno)));
2786 break;
2789 TALLOC_FREE(state);
2793 * Handle SMBecho requests in a forked child process
2795 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2797 int listener_pipe[2];
2798 int res;
2799 pid_t child;
2801 res = pipe(listener_pipe);
2802 if (res == -1) {
2803 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2804 return false;
2806 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2807 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2808 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2809 goto fail;
2812 child = sys_fork();
2813 if (child == 0) {
2814 NTSTATUS status;
2816 close(listener_pipe[0]);
2817 set_blocking(listener_pipe[1], false);
2819 status = reinit_after_fork(sconn->msg_ctx,
2820 smbd_event_context(),
2821 procid_self(), false);
2822 if (!NT_STATUS_IS_OK(status)) {
2823 DEBUG(1, ("reinit_after_fork failed: %s\n",
2824 nt_errstr(status)));
2825 exit(1);
2827 smbd_echo_loop(sconn, listener_pipe[1]);
2828 exit(0);
2830 close(listener_pipe[1]);
2831 listener_pipe[1] = -1;
2832 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2834 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2837 * Without smb signing this is the same as the normal smbd
2838 * listener. This needs to change once signing comes in.
2840 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2841 sconn,
2842 sconn->smb1.echo_handler.trusted_fd,
2843 EVENT_FD_READ,
2844 smbd_server_echo_handler,
2845 sconn);
2846 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2847 DEBUG(1, ("event_add_fd failed\n"));
2848 goto fail;
2851 return true;
2853 fail:
2854 if (listener_pipe[0] != -1) {
2855 close(listener_pipe[0]);
2857 if (listener_pipe[1] != -1) {
2858 close(listener_pipe[1]);
2860 sconn->smb1.echo_handler.trusted_fd = -1;
2861 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2862 close(sconn->smb1.echo_handler.socket_lock_fd);
2864 sconn->smb1.echo_handler.trusted_fd = -1;
2865 sconn->smb1.echo_handler.socket_lock_fd = -1;
2866 return false;
2869 #if CLUSTER_SUPPORT
2871 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2872 struct sockaddr_storage *srv,
2873 struct sockaddr_storage *clnt)
2875 struct ctdbd_connection *cconn;
2876 char tmp_addr[INET6_ADDRSTRLEN];
2877 char *addr;
2879 cconn = messaging_ctdbd_connection();
2880 if (cconn == NULL) {
2881 return NT_STATUS_NO_MEMORY;
2884 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2885 addr = talloc_strdup(cconn, tmp_addr);
2886 if (addr == NULL) {
2887 return NT_STATUS_NO_MEMORY;
2889 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2892 #endif
2894 /****************************************************************************
2895 Process commands from the client
2896 ****************************************************************************/
2898 void smbd_process(struct smbd_server_connection *sconn)
2900 TALLOC_CTX *frame = talloc_stackframe();
2901 struct sockaddr_storage ss;
2902 struct sockaddr *sa = NULL;
2903 socklen_t sa_socklen;
2904 struct tsocket_address *local_address = NULL;
2905 struct tsocket_address *remote_address = NULL;
2906 const char *remaddr = NULL;
2907 int ret;
2909 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2910 !lp_async_smb_echo_handler()) {
2912 * We're not making the decision here,
2913 * we're just allowing the client
2914 * to decide between SMB1 and SMB2
2915 * with the first negprot
2916 * packet.
2918 sconn->using_smb2 = true;
2921 /* Ensure child is set to blocking mode */
2922 set_blocking(sconn->sock,True);
2924 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2925 set_socket_options(sconn->sock, lp_socket_options());
2927 sa = (struct sockaddr *)(void *)&ss;
2928 sa_socklen = sizeof(ss);
2929 ret = getpeername(sconn->sock, sa, &sa_socklen);
2930 if (ret != 0) {
2931 int level = (errno == ENOTCONN)?2:0;
2932 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2933 exit_server_cleanly("getpeername() failed.\n");
2935 ret = tsocket_address_bsd_from_sockaddr(sconn,
2936 sa, sa_socklen,
2937 &remote_address);
2938 if (ret != 0) {
2939 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2940 __location__, strerror(errno)));
2941 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2944 sa = (struct sockaddr *)(void *)&ss;
2945 sa_socklen = sizeof(ss);
2946 ret = getsockname(sconn->sock, sa, &sa_socklen);
2947 if (ret != 0) {
2948 int level = (errno == ENOTCONN)?2:0;
2949 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2950 exit_server_cleanly("getsockname() failed.\n");
2952 ret = tsocket_address_bsd_from_sockaddr(sconn,
2953 sa, sa_socklen,
2954 &local_address);
2955 if (ret != 0) {
2956 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2957 __location__, strerror(errno)));
2958 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2961 sconn->local_address = local_address;
2962 sconn->remote_address = remote_address;
2964 if (tsocket_address_is_inet(remote_address, "ip")) {
2965 remaddr = tsocket_address_inet_addr_string(
2966 sconn->remote_address,
2967 talloc_tos());
2968 if (remaddr == NULL) {
2971 } else {
2972 remaddr = "0.0.0.0";
2975 /* this is needed so that we get decent entries
2976 in smbstatus for port 445 connects */
2977 set_remote_machine_name(remaddr, false);
2978 reload_services(sconn->msg_ctx, sconn->sock, true);
2981 * Before the first packet, check the global hosts allow/ hosts deny
2982 * parameters before doing any parsing of packets passed to us by the
2983 * client. This prevents attacks on our parsing code from hosts not in
2984 * the hosts allow list.
2987 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2988 sconn->client_id.name,
2989 sconn->client_id.addr)) {
2991 * send a negative session response "not listening on calling
2992 * name"
2994 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2995 DEBUG( 1, ("Connection denied from %s to %s\n",
2996 tsocket_address_string(remote_address, talloc_tos()),
2997 tsocket_address_string(local_address, talloc_tos())));
2998 (void)srv_send_smb(sconn,(char *)buf, false,
2999 0, false, NULL);
3000 exit_server_cleanly("connection denied");
3003 DEBUG(10, ("Connection allowed from %s to %s\n",
3004 tsocket_address_string(remote_address, talloc_tos()),
3005 tsocket_address_string(local_address, talloc_tos())));
3007 init_modules();
3009 smb_perfcount_init();
3011 if (!init_account_policy()) {
3012 exit_server("Could not open account policy tdb.\n");
3015 if (*lp_rootdir()) {
3016 if (chroot(lp_rootdir()) != 0) {
3017 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3018 exit_server("Failed to chroot()");
3020 if (chdir("/") == -1) {
3021 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3022 exit_server("Failed to chroot()");
3024 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3027 if (!srv_init_signing(sconn)) {
3028 exit_server("Failed to init smb_signing");
3031 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3032 exit_server("Failed to fork echo handler");
3035 /* Setup oplocks */
3036 if (!init_oplocks(sconn->msg_ctx))
3037 exit_server("Failed to init oplocks");
3039 /* register our message handlers */
3040 messaging_register(sconn->msg_ctx, NULL,
3041 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3042 messaging_register(sconn->msg_ctx, sconn,
3043 MSG_SMB_RELEASE_IP, msg_release_ip);
3044 messaging_register(sconn->msg_ctx, NULL,
3045 MSG_SMB_CLOSE_FILE, msg_close_file);
3048 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3049 * MSGs to all child processes
3051 messaging_deregister(sconn->msg_ctx,
3052 MSG_DEBUG, NULL);
3053 messaging_register(sconn->msg_ctx, NULL,
3054 MSG_DEBUG, debug_message);
3056 if ((lp_keepalive() != 0)
3057 && !(event_add_idle(smbd_event_context(), NULL,
3058 timeval_set(lp_keepalive(), 0),
3059 "keepalive", keepalive_fn,
3060 NULL))) {
3061 DEBUG(0, ("Could not add keepalive event\n"));
3062 exit(1);
3065 if (!(event_add_idle(smbd_event_context(), NULL,
3066 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3067 "deadtime", deadtime_fn, sconn))) {
3068 DEBUG(0, ("Could not add deadtime event\n"));
3069 exit(1);
3072 if (!(event_add_idle(smbd_event_context(), NULL,
3073 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3074 "housekeeping", housekeeping_fn, sconn))) {
3075 DEBUG(0, ("Could not add housekeeping event\n"));
3076 exit(1);
3079 #ifdef CLUSTER_SUPPORT
3081 if (lp_clustering()) {
3083 * We need to tell ctdb about our client's TCP
3084 * connection, so that for failover ctdbd can send
3085 * tickle acks, triggering a reconnection by the
3086 * client.
3089 struct sockaddr_storage srv, clnt;
3091 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3092 NTSTATUS status;
3093 status = smbd_register_ips(sconn, &srv, &clnt);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3096 nt_errstr(status)));
3098 } else
3100 DEBUG(0,("Unable to get tcp info for "
3101 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3102 strerror(errno)));
3106 #endif
3108 sconn->nbt.got_session = false;
3110 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3112 sconn->smb1.sessions.done_sesssetup = false;
3113 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3114 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3115 /* users from session setup */
3116 sconn->smb1.sessions.session_userlist = NULL;
3117 /* workgroup from session setup. */
3118 sconn->smb1.sessions.session_workgroup = NULL;
3119 /* this holds info on user ids that are already validated for this VC */
3120 sconn->smb1.sessions.validated_users = NULL;
3121 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3122 sconn->smb1.sessions.num_validated_vuids = 0;
3124 conn_init(sconn);
3125 if (!init_dptrs(sconn)) {
3126 exit_server("init_dptrs() failed");
3129 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3130 sconn,
3131 sconn->sock,
3132 EVENT_FD_READ,
3133 smbd_server_connection_handler,
3134 sconn);
3135 if (!sconn->smb1.fde) {
3136 exit_server("failed to create smbd_server_connection fde");
3139 TALLOC_FREE(frame);
3141 while (True) {
3142 NTSTATUS status;
3144 frame = talloc_stackframe_pool(8192);
3146 errno = 0;
3148 status = smbd_server_connection_loop_once(sconn);
3149 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3150 !NT_STATUS_IS_OK(status)) {
3151 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3152 " exiting\n", nt_errstr(status)));
3153 break;
3156 TALLOC_FREE(frame);
3159 exit_server_cleanly(NULL);
3162 bool req_is_in_chain(struct smb_request *req)
3164 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3166 * We're right now handling a subsequent request, so we must
3167 * be in a chain
3169 return true;
3172 if (!is_andx_req(req->cmd)) {
3173 return false;
3176 if (req->wct < 2) {
3178 * Okay, an illegal request, but definitely not chained :-)
3180 return false;
3183 return (CVAL(req->vwv+0, 0) != 0xFF);