nsswitch: Add wbinfo --sids-to-unix-ids
[Samba.git] / source3 / smbd / process.c
blobf290e1d82b09962f750b978f2614a062b92c043f
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 "system/filesys.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "librpc/gen_ndr/netlogon.h"
26 #include "../lib/async_req/async_sock.h"
27 #include "ctdbd_conn.h"
28 #include "../lib/util/select.h"
29 #include "printing/pcap.h"
30 #include "system/select.h"
31 #include "passdb.h"
32 #include "auth.h"
33 #include "messages.h"
35 extern bool global_machine_password_needs_changing;
37 static void construct_reply_common(struct smb_request *req, const char *inbuf,
38 char *outbuf);
39 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
41 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
43 bool ok;
45 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
46 return true;
49 sconn->smb1.echo_handler.ref_count++;
51 if (sconn->smb1.echo_handler.ref_count > 1) {
52 return true;
55 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
57 do {
58 ok = fcntl_lock(
59 sconn->smb1.echo_handler.socket_lock_fd,
60 SMB_F_SETLKW, 0, 0, F_WRLCK);
61 } while (!ok && (errno == EINTR));
63 if (!ok) {
64 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
65 return false;
68 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
70 return true;
73 void smbd_lock_socket(struct smbd_server_connection *sconn)
75 if (!smbd_lock_socket_internal(sconn)) {
76 exit_server_cleanly("failed to lock socket");
80 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
82 bool ok;
84 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
85 return true;
88 sconn->smb1.echo_handler.ref_count--;
90 if (sconn->smb1.echo_handler.ref_count > 0) {
91 return true;
94 do {
95 ok = fcntl_lock(
96 sconn->smb1.echo_handler.socket_lock_fd,
97 SMB_F_SETLKW, 0, 0, F_UNLCK);
98 } while (!ok && (errno == EINTR));
100 if (!ok) {
101 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
102 return false;
105 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
107 return true;
110 void smbd_unlock_socket(struct smbd_server_connection *sconn)
112 if (!smbd_unlock_socket_internal(sconn)) {
113 exit_server_cleanly("failed to unlock socket");
117 /* Accessor function for smb_read_error for smbd functions. */
119 /****************************************************************************
120 Send an smb to a fd.
121 ****************************************************************************/
123 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
124 bool do_signing, uint32_t seqnum,
125 bool do_encrypt,
126 struct smb_perfcount_data *pcd)
128 size_t len = 0;
129 size_t nwritten=0;
130 ssize_t ret;
131 char *buf_out = buffer;
133 smbd_lock_socket(sconn);
135 if (do_signing) {
136 /* Sign the outgoing packet if required. */
137 srv_calculate_sign_mac(sconn, buf_out, seqnum);
140 if (do_encrypt) {
141 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
142 if (!NT_STATUS_IS_OK(status)) {
143 DEBUG(0, ("send_smb: SMB encryption failed "
144 "on outgoing packet! Error %s\n",
145 nt_errstr(status) ));
146 goto out;
150 len = smb_len(buf_out) + 4;
152 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
153 if (ret <= 0) {
155 char addr[INET6_ADDRSTRLEN];
157 * Try and give an error message saying what
158 * client failed.
160 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
161 (int)sys_getpid(), (int)len,
162 get_peer_addr(sconn->sock, addr, sizeof(addr)),
163 (int)ret, strerror(errno) ));
165 srv_free_enc_buffer(buf_out);
166 goto out;
169 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
170 srv_free_enc_buffer(buf_out);
171 out:
172 SMB_PERFCOUNT_END(pcd);
174 smbd_unlock_socket(sconn);
175 return true;
178 /*******************************************************************
179 Setup the word count and byte count for a smb message.
180 ********************************************************************/
182 int srv_set_message(char *buf,
183 int num_words,
184 int num_bytes,
185 bool zero)
187 if (zero && (num_words || num_bytes)) {
188 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
190 SCVAL(buf,smb_wct,num_words);
191 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
192 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
193 return (smb_size + num_words*2 + num_bytes);
196 static bool valid_smb_header(const uint8_t *inbuf)
198 if (is_encrypted_packet(inbuf)) {
199 return true;
202 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
203 * but it just looks weird to call strncmp for this one.
205 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
208 /* Socket functions for smbd packet processing. */
210 static bool valid_packet_size(size_t len)
213 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
214 * of header. Don't print the error if this fits.... JRA.
217 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
218 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
219 (unsigned long)len));
220 return false;
222 return true;
225 static NTSTATUS read_packet_remainder(int fd, char *buffer,
226 unsigned int timeout, ssize_t len)
228 NTSTATUS status;
230 if (len <= 0) {
231 return NT_STATUS_OK;
234 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
235 if (!NT_STATUS_IS_OK(status)) {
236 char addr[INET6_ADDRSTRLEN];
237 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
238 "error = %s.\n",
239 get_peer_addr(fd, addr, sizeof(addr)),
240 nt_errstr(status)));
242 return status;
245 /****************************************************************************
246 Attempt a zerocopy writeX read. We know here that len > smb_size-4
247 ****************************************************************************/
250 * Unfortunately, earlier versions of smbclient/libsmbclient
251 * don't send this "standard" writeX header. I've fixed this
252 * for 3.2 but we'll use the old method with earlier versions.
253 * Windows and CIFSFS at least use this standard size. Not
254 * sure about MacOSX.
257 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
258 (2*14) + /* word count (including bcc) */ \
259 1 /* pad byte */)
261 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
262 const char lenbuf[4],
263 struct smbd_server_connection *sconn,
264 char **buffer,
265 unsigned int timeout,
266 size_t *p_unread,
267 size_t *len_ret)
269 /* Size of a WRITEX call (+4 byte len). */
270 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
271 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
272 ssize_t toread;
273 NTSTATUS status;
275 memcpy(writeX_header, lenbuf, 4);
277 status = read_fd_with_timeout(
278 sconn->sock, writeX_header + 4,
279 STANDARD_WRITE_AND_X_HEADER_SIZE,
280 STANDARD_WRITE_AND_X_HEADER_SIZE,
281 timeout, NULL);
283 if (!NT_STATUS_IS_OK(status)) {
284 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
285 "error = %s.\n", sconn->client_id.addr,
286 nt_errstr(status)));
287 return status;
291 * Ok - now try and see if this is a possible
292 * valid writeX call.
295 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
297 * If the data offset is beyond what
298 * we've read, drain the extra bytes.
300 uint16_t doff = SVAL(writeX_header,smb_vwv11);
301 ssize_t newlen;
303 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
304 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
305 if (drain_socket(sconn->sock, drain) != drain) {
306 smb_panic("receive_smb_raw_talloc_partial_read:"
307 " failed to drain pending bytes");
309 } else {
310 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
313 /* Spoof down the length and null out the bcc. */
314 set_message_bcc(writeX_header, 0);
315 newlen = smb_len(writeX_header);
317 /* Copy the header we've written. */
319 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
320 writeX_header,
321 sizeof(writeX_header));
323 if (*buffer == NULL) {
324 DEBUG(0, ("Could not allocate inbuf of length %d\n",
325 (int)sizeof(writeX_header)));
326 return NT_STATUS_NO_MEMORY;
329 /* Work out the remaining bytes. */
330 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
331 *len_ret = newlen + 4;
332 return NT_STATUS_OK;
335 if (!valid_packet_size(len)) {
336 return NT_STATUS_INVALID_PARAMETER;
340 * Not a valid writeX call. Just do the standard
341 * talloc and return.
344 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
346 if (*buffer == NULL) {
347 DEBUG(0, ("Could not allocate inbuf of length %d\n",
348 (int)len+4));
349 return NT_STATUS_NO_MEMORY;
352 /* Copy in what we already read. */
353 memcpy(*buffer,
354 writeX_header,
355 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
356 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
358 if(toread > 0) {
359 status = read_packet_remainder(
360 sconn->sock,
361 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
362 timeout, toread);
364 if (!NT_STATUS_IS_OK(status)) {
365 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
366 nt_errstr(status)));
367 return status;
371 *len_ret = len + 4;
372 return NT_STATUS_OK;
375 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
376 struct smbd_server_connection *sconn,
377 char **buffer, unsigned int timeout,
378 size_t *p_unread, size_t *plen)
380 char lenbuf[4];
381 size_t len;
382 int min_recv_size = lp_min_receive_file_size();
383 NTSTATUS status;
385 *p_unread = 0;
387 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
388 &len);
389 if (!NT_STATUS_IS_OK(status)) {
390 return status;
393 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
394 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
395 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
396 !srv_is_signing_active(sconn) &&
397 sconn->smb1.echo_handler.trusted_fde == NULL) {
399 return receive_smb_raw_talloc_partial_read(
400 mem_ctx, lenbuf, sconn, buffer, timeout,
401 p_unread, plen);
404 if (!valid_packet_size(len)) {
405 return NT_STATUS_INVALID_PARAMETER;
409 * The +4 here can't wrap, we've checked the length above already.
412 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
414 if (*buffer == NULL) {
415 DEBUG(0, ("Could not allocate inbuf of length %d\n",
416 (int)len+4));
417 return NT_STATUS_NO_MEMORY;
420 memcpy(*buffer, lenbuf, sizeof(lenbuf));
422 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
423 if (!NT_STATUS_IS_OK(status)) {
424 return status;
427 *plen = len + 4;
428 return NT_STATUS_OK;
431 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
432 struct smbd_server_connection *sconn,
433 char **buffer, unsigned int timeout,
434 size_t *p_unread, bool *p_encrypted,
435 size_t *p_len,
436 uint32_t *seqnum,
437 bool trusted_channel)
439 size_t len = 0;
440 NTSTATUS status;
442 *p_encrypted = false;
444 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
445 p_unread, &len);
446 if (!NT_STATUS_IS_OK(status)) {
447 DEBUG(1, ("read_smb_length_return_keepalive failed for "
448 "client %s read error = %s.\n",
449 sconn->client_id.addr, nt_errstr(status)));
450 return status;
453 if (is_encrypted_packet((uint8_t *)*buffer)) {
454 status = srv_decrypt_buffer(*buffer);
455 if (!NT_STATUS_IS_OK(status)) {
456 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
457 "incoming packet! Error %s\n",
458 nt_errstr(status) ));
459 return status;
461 *p_encrypted = true;
464 /* Check the incoming SMB signature. */
465 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
466 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
467 "incoming packet!\n"));
468 return NT_STATUS_INVALID_NETWORK_RESPONSE;
471 *p_len = len;
472 return NT_STATUS_OK;
476 * Initialize a struct smb_request from an inbuf
479 static bool init_smb_request(struct smb_request *req,
480 struct smbd_server_connection *sconn,
481 const uint8 *inbuf,
482 size_t unread_bytes, bool encrypted,
483 uint32_t seqnum)
485 size_t req_size = smb_len(inbuf) + 4;
486 /* Ensure we have at least smb_size bytes. */
487 if (req_size < smb_size) {
488 DEBUG(0,("init_smb_request: invalid request size %u\n",
489 (unsigned int)req_size ));
490 return false;
492 req->cmd = CVAL(inbuf, smb_com);
493 req->flags2 = SVAL(inbuf, smb_flg2);
494 req->smbpid = SVAL(inbuf, smb_pid);
495 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
496 req->seqnum = seqnum;
497 req->vuid = SVAL(inbuf, smb_uid);
498 req->tid = SVAL(inbuf, smb_tid);
499 req->wct = CVAL(inbuf, smb_wct);
500 req->vwv = (uint16_t *)(inbuf+smb_vwv);
501 req->buflen = smb_buflen(inbuf);
502 req->buf = (const uint8_t *)smb_buf(inbuf);
503 req->unread_bytes = unread_bytes;
504 req->encrypted = encrypted;
505 req->sconn = sconn;
506 req->conn = conn_find(sconn,req->tid);
507 req->chain_fsp = NULL;
508 req->chain_outbuf = NULL;
509 req->done = false;
510 req->smb2req = NULL;
511 smb_init_perfcount_data(&req->pcd);
513 /* Ensure we have at least wct words and 2 bytes of bcc. */
514 if (smb_size + req->wct*2 > req_size) {
515 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
516 (unsigned int)req->wct,
517 (unsigned int)req_size));
518 return false;
520 /* Ensure bcc is correct. */
521 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
522 DEBUG(0,("init_smb_request: invalid bcc number %u "
523 "(wct = %u, size %u)\n",
524 (unsigned int)req->buflen,
525 (unsigned int)req->wct,
526 (unsigned int)req_size));
527 return false;
530 req->outbuf = NULL;
531 return true;
534 static void process_smb(struct smbd_server_connection *conn,
535 uint8_t *inbuf, size_t nread, size_t unread_bytes,
536 uint32_t seqnum, bool encrypted,
537 struct smb_perfcount_data *deferred_pcd);
539 static void smbd_deferred_open_timer(struct event_context *ev,
540 struct timed_event *te,
541 struct timeval _tval,
542 void *private_data)
544 struct pending_message_list *msg = talloc_get_type(private_data,
545 struct pending_message_list);
546 TALLOC_CTX *mem_ctx = talloc_tos();
547 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
548 uint8_t *inbuf;
550 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
551 msg->buf.length);
552 if (inbuf == NULL) {
553 exit_server("smbd_deferred_open_timer: talloc failed\n");
554 return;
557 /* We leave this message on the queue so the open code can
558 know this is a retry. */
559 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
560 (unsigned long long)mid ));
562 /* Mark the message as processed so this is not
563 * re-processed in error. */
564 msg->processed = true;
566 process_smb(smbd_server_conn, inbuf,
567 msg->buf.length, 0,
568 msg->seqnum, msg->encrypted, &msg->pcd);
570 /* If it's still there and was processed, remove it. */
571 msg = get_deferred_open_message_smb(mid);
572 if (msg && msg->processed) {
573 remove_deferred_open_message_smb(mid);
577 /****************************************************************************
578 Function to push a message onto the tail of a linked list of smb messages ready
579 for processing.
580 ****************************************************************************/
582 static bool push_queued_message(struct smb_request *req,
583 struct timeval request_time,
584 struct timeval end_time,
585 char *private_data, size_t private_len)
587 int msg_len = smb_len(req->inbuf) + 4;
588 struct pending_message_list *msg;
590 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
592 if(msg == NULL) {
593 DEBUG(0,("push_message: malloc fail (1)\n"));
594 return False;
597 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
598 if(msg->buf.data == NULL) {
599 DEBUG(0,("push_message: malloc fail (2)\n"));
600 TALLOC_FREE(msg);
601 return False;
604 msg->request_time = request_time;
605 msg->seqnum = req->seqnum;
606 msg->encrypted = req->encrypted;
607 msg->processed = false;
608 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
610 if (private_data) {
611 msg->private_data = data_blob_talloc(msg, private_data,
612 private_len);
613 if (msg->private_data.data == NULL) {
614 DEBUG(0,("push_message: malloc fail (3)\n"));
615 TALLOC_FREE(msg);
616 return False;
620 msg->te = event_add_timed(smbd_event_context(),
621 msg,
622 end_time,
623 smbd_deferred_open_timer,
624 msg);
625 if (!msg->te) {
626 DEBUG(0,("push_message: event_add_timed failed\n"));
627 TALLOC_FREE(msg);
628 return false;
631 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
633 DEBUG(10,("push_message: pushed message length %u on "
634 "deferred_open_queue\n", (unsigned int)msg_len));
636 return True;
639 /****************************************************************************
640 Function to delete a sharing violation open message by mid.
641 ****************************************************************************/
643 void remove_deferred_open_message_smb(uint64_t mid)
645 struct pending_message_list *pml;
647 if (smbd_server_conn->using_smb2) {
648 remove_deferred_open_message_smb2(smbd_server_conn, mid);
649 return;
652 for (pml = deferred_open_queue; pml; pml = pml->next) {
653 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
654 DEBUG(10,("remove_deferred_open_message_smb: "
655 "deleting mid %llu len %u\n",
656 (unsigned long long)mid,
657 (unsigned int)pml->buf.length ));
658 DLIST_REMOVE(deferred_open_queue, pml);
659 TALLOC_FREE(pml);
660 return;
665 /****************************************************************************
666 Move a sharing violation open retry message to the front of the list and
667 schedule it for immediate processing.
668 ****************************************************************************/
670 void schedule_deferred_open_message_smb(uint64_t mid)
672 struct pending_message_list *pml;
673 int i = 0;
675 if (smbd_server_conn->using_smb2) {
676 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
677 return;
680 for (pml = deferred_open_queue; pml; pml = pml->next) {
681 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
683 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
684 "msg_mid = %llu\n",
685 i++,
686 (unsigned long long)msg_mid ));
688 if (mid == msg_mid) {
689 struct timed_event *te;
691 if (pml->processed) {
692 /* A processed message should not be
693 * rescheduled. */
694 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
695 "message mid %llu was already processed\n",
696 (unsigned long long)msg_mid ));
697 continue;
700 DEBUG(10,("schedule_deferred_open_message_smb: "
701 "scheduling mid %llu\n",
702 (unsigned long long)mid ));
704 te = event_add_timed(smbd_event_context(),
705 pml,
706 timeval_zero(),
707 smbd_deferred_open_timer,
708 pml);
709 if (!te) {
710 DEBUG(10,("schedule_deferred_open_message_smb: "
711 "event_add_timed() failed, "
712 "skipping mid %llu\n",
713 (unsigned long long)msg_mid ));
716 TALLOC_FREE(pml->te);
717 pml->te = te;
718 DLIST_PROMOTE(deferred_open_queue, pml);
719 return;
723 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
724 "find message mid %llu\n",
725 (unsigned long long)mid ));
728 /****************************************************************************
729 Return true if this mid is on the deferred queue and was not yet processed.
730 ****************************************************************************/
732 bool open_was_deferred(uint64_t mid)
734 struct pending_message_list *pml;
736 if (smbd_server_conn->using_smb2) {
737 return open_was_deferred_smb2(smbd_server_conn, mid);
740 for (pml = deferred_open_queue; pml; pml = pml->next) {
741 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
742 return True;
745 return False;
748 /****************************************************************************
749 Return the message queued by this mid.
750 ****************************************************************************/
752 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
754 struct pending_message_list *pml;
756 for (pml = deferred_open_queue; pml; pml = pml->next) {
757 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
758 return pml;
761 return NULL;
764 /****************************************************************************
765 Get the state data queued by this mid.
766 ****************************************************************************/
768 bool get_deferred_open_message_state(struct smb_request *smbreq,
769 struct timeval *p_request_time,
770 void **pp_state)
772 struct pending_message_list *pml;
774 if (smbd_server_conn->using_smb2) {
775 return get_deferred_open_message_state_smb2(smbreq->smb2req,
776 p_request_time,
777 pp_state);
780 pml = get_deferred_open_message_smb(smbreq->mid);
781 if (!pml) {
782 return false;
784 if (p_request_time) {
785 *p_request_time = pml->request_time;
787 if (pp_state) {
788 *pp_state = (void *)pml->private_data.data;
790 return true;
793 /****************************************************************************
794 Function to push a deferred open smb message onto a linked list of local smb
795 messages ready for processing.
796 ****************************************************************************/
798 bool push_deferred_open_message_smb(struct smb_request *req,
799 struct timeval request_time,
800 struct timeval timeout,
801 struct file_id id,
802 char *private_data, size_t priv_len)
804 struct timeval end_time;
806 if (req->smb2req) {
807 return push_deferred_open_message_smb2(req->smb2req,
808 request_time,
809 timeout,
811 private_data,
812 priv_len);
815 if (req->unread_bytes) {
816 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
817 "unread_bytes = %u\n",
818 (unsigned int)req->unread_bytes ));
819 smb_panic("push_deferred_open_message_smb: "
820 "logic error unread_bytes != 0" );
823 end_time = timeval_sum(&request_time, &timeout);
825 DEBUG(10,("push_deferred_open_message_smb: pushing message "
826 "len %u mid %llu timeout time [%u.%06u]\n",
827 (unsigned int) smb_len(req->inbuf)+4,
828 (unsigned long long)req->mid,
829 (unsigned int)end_time.tv_sec,
830 (unsigned int)end_time.tv_usec));
832 return push_queued_message(req, request_time, end_time,
833 private_data, priv_len);
836 struct idle_event {
837 struct timed_event *te;
838 struct timeval interval;
839 char *name;
840 bool (*handler)(const struct timeval *now, void *private_data);
841 void *private_data;
844 static void smbd_idle_event_handler(struct event_context *ctx,
845 struct timed_event *te,
846 struct timeval now,
847 void *private_data)
849 struct idle_event *event =
850 talloc_get_type_abort(private_data, struct idle_event);
852 TALLOC_FREE(event->te);
854 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
855 event->name, event->te));
857 if (!event->handler(&now, event->private_data)) {
858 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
859 event->name, event->te));
860 /* Don't repeat, delete ourselves */
861 TALLOC_FREE(event);
862 return;
865 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
866 event->name, event->te));
868 event->te = event_add_timed(ctx, event,
869 timeval_sum(&now, &event->interval),
870 smbd_idle_event_handler, event);
872 /* We can't do much but fail here. */
873 SMB_ASSERT(event->te != NULL);
876 struct idle_event *event_add_idle(struct event_context *event_ctx,
877 TALLOC_CTX *mem_ctx,
878 struct timeval interval,
879 const char *name,
880 bool (*handler)(const struct timeval *now,
881 void *private_data),
882 void *private_data)
884 struct idle_event *result;
885 struct timeval now = timeval_current();
887 result = TALLOC_P(mem_ctx, struct idle_event);
888 if (result == NULL) {
889 DEBUG(0, ("talloc failed\n"));
890 return NULL;
893 result->interval = interval;
894 result->handler = handler;
895 result->private_data = private_data;
897 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
898 DEBUG(0, ("talloc failed\n"));
899 TALLOC_FREE(result);
900 return NULL;
903 result->te = event_add_timed(event_ctx, result,
904 timeval_sum(&now, &interval),
905 smbd_idle_event_handler, result);
906 if (result->te == NULL) {
907 DEBUG(0, ("event_add_timed failed\n"));
908 TALLOC_FREE(result);
909 return NULL;
912 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
913 return result;
916 static void smbd_sig_term_handler(struct tevent_context *ev,
917 struct tevent_signal *se,
918 int signum,
919 int count,
920 void *siginfo,
921 void *private_data)
923 exit_server_cleanly("termination signal");
926 void smbd_setup_sig_term_handler(void)
928 struct tevent_signal *se;
930 se = tevent_add_signal(smbd_event_context(),
931 smbd_event_context(),
932 SIGTERM, 0,
933 smbd_sig_term_handler,
934 NULL);
935 if (!se) {
936 exit_server("failed to setup SIGTERM handler");
940 static void smbd_sig_hup_handler(struct tevent_context *ev,
941 struct tevent_signal *se,
942 int signum,
943 int count,
944 void *siginfo,
945 void *private_data)
947 struct messaging_context *msg_ctx = talloc_get_type_abort(
948 private_data, struct messaging_context);
949 change_to_root_user();
950 DEBUG(1,("Reloading services after SIGHUP\n"));
951 reload_services(msg_ctx, smbd_server_conn->sock, False);
952 if (am_parent) {
953 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
957 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
958 struct messaging_context *msg_ctx)
960 struct tevent_signal *se;
962 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
963 msg_ctx);
964 if (!se) {
965 exit_server("failed to setup SIGHUP handler");
969 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
971 int timeout;
972 int num_pfds = 0;
973 int ret;
974 bool retry;
976 timeout = SMBD_SELECT_TIMEOUT * 1000;
979 * Are there any timed events waiting ? If so, ensure we don't
980 * select for longer than it would take to wait for them.
983 event_add_to_poll_args(smbd_event_context(), conn,
984 &conn->pfds, &num_pfds, &timeout);
986 /* Process a signal and timed events now... */
987 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
988 return NT_STATUS_RETRY;
992 int sav;
993 START_PROFILE(smbd_idle);
995 ret = sys_poll(conn->pfds, num_pfds, timeout);
996 sav = errno;
998 END_PROFILE(smbd_idle);
999 errno = sav;
1002 if (ret == -1 && errno != EINTR) {
1003 return map_nt_error_from_unix(errno);
1006 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1007 num_pfds);
1008 if (retry) {
1009 return NT_STATUS_RETRY;
1012 /* Did we timeout ? */
1013 if (ret == 0) {
1014 return NT_STATUS_RETRY;
1017 /* should not be reached */
1018 return NT_STATUS_INTERNAL_ERROR;
1022 * Only allow 5 outstanding trans requests. We're allocating memory, so
1023 * prevent a DoS.
1026 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1028 int count = 0;
1029 for (; list != NULL; list = list->next) {
1031 if (list->mid == mid) {
1032 return NT_STATUS_INVALID_PARAMETER;
1035 count += 1;
1037 if (count > 5) {
1038 return NT_STATUS_INSUFFICIENT_RESOURCES;
1041 return NT_STATUS_OK;
1045 These flags determine some of the permissions required to do an operation
1047 Note that I don't set NEED_WRITE on some write operations because they
1048 are used by some brain-dead clients when printing, and I don't want to
1049 force write permissions on print services.
1051 #define AS_USER (1<<0)
1052 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1053 #define TIME_INIT (1<<2)
1054 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1055 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1056 #define DO_CHDIR (1<<6)
1059 define a list of possible SMB messages and their corresponding
1060 functions. Any message that has a NULL function is unimplemented -
1061 please feel free to contribute implementations!
1063 static const struct smb_message_struct {
1064 const char *name;
1065 void (*fn)(struct smb_request *req);
1066 int flags;
1067 } smb_messages[256] = {
1069 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1070 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1071 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1072 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1073 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1074 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1075 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1076 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1077 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1078 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1079 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1080 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1081 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1082 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1083 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1084 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1085 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1086 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1087 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1088 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1089 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1090 /* 0x15 */ { NULL, NULL, 0 },
1091 /* 0x16 */ { NULL, NULL, 0 },
1092 /* 0x17 */ { NULL, NULL, 0 },
1093 /* 0x18 */ { NULL, NULL, 0 },
1094 /* 0x19 */ { NULL, NULL, 0 },
1095 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1096 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1097 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1098 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1099 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1100 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1101 /* 0x20 */ { "SMBwritec", NULL,0},
1102 /* 0x21 */ { NULL, NULL, 0 },
1103 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1104 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1105 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1106 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1107 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1108 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1109 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1110 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1111 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1112 /* 0x2b */ { "SMBecho",reply_echo,0},
1113 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1114 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1115 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1116 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1117 /* 0x30 */ { NULL, NULL, 0 },
1118 /* 0x31 */ { NULL, NULL, 0 },
1119 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1120 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1121 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1122 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1123 /* 0x36 */ { NULL, NULL, 0 },
1124 /* 0x37 */ { NULL, NULL, 0 },
1125 /* 0x38 */ { NULL, NULL, 0 },
1126 /* 0x39 */ { NULL, NULL, 0 },
1127 /* 0x3a */ { NULL, NULL, 0 },
1128 /* 0x3b */ { NULL, NULL, 0 },
1129 /* 0x3c */ { NULL, NULL, 0 },
1130 /* 0x3d */ { NULL, NULL, 0 },
1131 /* 0x3e */ { NULL, NULL, 0 },
1132 /* 0x3f */ { NULL, NULL, 0 },
1133 /* 0x40 */ { NULL, NULL, 0 },
1134 /* 0x41 */ { NULL, NULL, 0 },
1135 /* 0x42 */ { NULL, NULL, 0 },
1136 /* 0x43 */ { NULL, NULL, 0 },
1137 /* 0x44 */ { NULL, NULL, 0 },
1138 /* 0x45 */ { NULL, NULL, 0 },
1139 /* 0x46 */ { NULL, NULL, 0 },
1140 /* 0x47 */ { NULL, NULL, 0 },
1141 /* 0x48 */ { NULL, NULL, 0 },
1142 /* 0x49 */ { NULL, NULL, 0 },
1143 /* 0x4a */ { NULL, NULL, 0 },
1144 /* 0x4b */ { NULL, NULL, 0 },
1145 /* 0x4c */ { NULL, NULL, 0 },
1146 /* 0x4d */ { NULL, NULL, 0 },
1147 /* 0x4e */ { NULL, NULL, 0 },
1148 /* 0x4f */ { NULL, NULL, 0 },
1149 /* 0x50 */ { NULL, NULL, 0 },
1150 /* 0x51 */ { NULL, NULL, 0 },
1151 /* 0x52 */ { NULL, NULL, 0 },
1152 /* 0x53 */ { NULL, NULL, 0 },
1153 /* 0x54 */ { NULL, NULL, 0 },
1154 /* 0x55 */ { NULL, NULL, 0 },
1155 /* 0x56 */ { NULL, NULL, 0 },
1156 /* 0x57 */ { NULL, NULL, 0 },
1157 /* 0x58 */ { NULL, NULL, 0 },
1158 /* 0x59 */ { NULL, NULL, 0 },
1159 /* 0x5a */ { NULL, NULL, 0 },
1160 /* 0x5b */ { NULL, NULL, 0 },
1161 /* 0x5c */ { NULL, NULL, 0 },
1162 /* 0x5d */ { NULL, NULL, 0 },
1163 /* 0x5e */ { NULL, NULL, 0 },
1164 /* 0x5f */ { NULL, NULL, 0 },
1165 /* 0x60 */ { NULL, NULL, 0 },
1166 /* 0x61 */ { NULL, NULL, 0 },
1167 /* 0x62 */ { NULL, NULL, 0 },
1168 /* 0x63 */ { NULL, NULL, 0 },
1169 /* 0x64 */ { NULL, NULL, 0 },
1170 /* 0x65 */ { NULL, NULL, 0 },
1171 /* 0x66 */ { NULL, NULL, 0 },
1172 /* 0x67 */ { NULL, NULL, 0 },
1173 /* 0x68 */ { NULL, NULL, 0 },
1174 /* 0x69 */ { NULL, NULL, 0 },
1175 /* 0x6a */ { NULL, NULL, 0 },
1176 /* 0x6b */ { NULL, NULL, 0 },
1177 /* 0x6c */ { NULL, NULL, 0 },
1178 /* 0x6d */ { NULL, NULL, 0 },
1179 /* 0x6e */ { NULL, NULL, 0 },
1180 /* 0x6f */ { NULL, NULL, 0 },
1181 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1182 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1183 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1184 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1185 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1186 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1187 /* 0x76 */ { NULL, NULL, 0 },
1188 /* 0x77 */ { NULL, NULL, 0 },
1189 /* 0x78 */ { NULL, NULL, 0 },
1190 /* 0x79 */ { NULL, NULL, 0 },
1191 /* 0x7a */ { NULL, NULL, 0 },
1192 /* 0x7b */ { NULL, NULL, 0 },
1193 /* 0x7c */ { NULL, NULL, 0 },
1194 /* 0x7d */ { NULL, NULL, 0 },
1195 /* 0x7e */ { NULL, NULL, 0 },
1196 /* 0x7f */ { NULL, NULL, 0 },
1197 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1198 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1199 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1200 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1201 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1202 /* 0x85 */ { NULL, NULL, 0 },
1203 /* 0x86 */ { NULL, NULL, 0 },
1204 /* 0x87 */ { NULL, NULL, 0 },
1205 /* 0x88 */ { NULL, NULL, 0 },
1206 /* 0x89 */ { NULL, NULL, 0 },
1207 /* 0x8a */ { NULL, NULL, 0 },
1208 /* 0x8b */ { NULL, NULL, 0 },
1209 /* 0x8c */ { NULL, NULL, 0 },
1210 /* 0x8d */ { NULL, NULL, 0 },
1211 /* 0x8e */ { NULL, NULL, 0 },
1212 /* 0x8f */ { NULL, NULL, 0 },
1213 /* 0x90 */ { NULL, NULL, 0 },
1214 /* 0x91 */ { NULL, NULL, 0 },
1215 /* 0x92 */ { NULL, NULL, 0 },
1216 /* 0x93 */ { NULL, NULL, 0 },
1217 /* 0x94 */ { NULL, NULL, 0 },
1218 /* 0x95 */ { NULL, NULL, 0 },
1219 /* 0x96 */ { NULL, NULL, 0 },
1220 /* 0x97 */ { NULL, NULL, 0 },
1221 /* 0x98 */ { NULL, NULL, 0 },
1222 /* 0x99 */ { NULL, NULL, 0 },
1223 /* 0x9a */ { NULL, NULL, 0 },
1224 /* 0x9b */ { NULL, NULL, 0 },
1225 /* 0x9c */ { NULL, NULL, 0 },
1226 /* 0x9d */ { NULL, NULL, 0 },
1227 /* 0x9e */ { NULL, NULL, 0 },
1228 /* 0x9f */ { NULL, NULL, 0 },
1229 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1230 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1231 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1232 /* 0xa3 */ { NULL, NULL, 0 },
1233 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1234 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1235 /* 0xa6 */ { NULL, NULL, 0 },
1236 /* 0xa7 */ { NULL, NULL, 0 },
1237 /* 0xa8 */ { NULL, NULL, 0 },
1238 /* 0xa9 */ { NULL, NULL, 0 },
1239 /* 0xaa */ { NULL, NULL, 0 },
1240 /* 0xab */ { NULL, NULL, 0 },
1241 /* 0xac */ { NULL, NULL, 0 },
1242 /* 0xad */ { NULL, NULL, 0 },
1243 /* 0xae */ { NULL, NULL, 0 },
1244 /* 0xaf */ { NULL, NULL, 0 },
1245 /* 0xb0 */ { NULL, NULL, 0 },
1246 /* 0xb1 */ { NULL, NULL, 0 },
1247 /* 0xb2 */ { NULL, NULL, 0 },
1248 /* 0xb3 */ { NULL, NULL, 0 },
1249 /* 0xb4 */ { NULL, NULL, 0 },
1250 /* 0xb5 */ { NULL, NULL, 0 },
1251 /* 0xb6 */ { NULL, NULL, 0 },
1252 /* 0xb7 */ { NULL, NULL, 0 },
1253 /* 0xb8 */ { NULL, NULL, 0 },
1254 /* 0xb9 */ { NULL, NULL, 0 },
1255 /* 0xba */ { NULL, NULL, 0 },
1256 /* 0xbb */ { NULL, NULL, 0 },
1257 /* 0xbc */ { NULL, NULL, 0 },
1258 /* 0xbd */ { NULL, NULL, 0 },
1259 /* 0xbe */ { NULL, NULL, 0 },
1260 /* 0xbf */ { NULL, NULL, 0 },
1261 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1262 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1263 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1264 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1265 /* 0xc4 */ { NULL, NULL, 0 },
1266 /* 0xc5 */ { NULL, NULL, 0 },
1267 /* 0xc6 */ { NULL, NULL, 0 },
1268 /* 0xc7 */ { NULL, NULL, 0 },
1269 /* 0xc8 */ { NULL, NULL, 0 },
1270 /* 0xc9 */ { NULL, NULL, 0 },
1271 /* 0xca */ { NULL, NULL, 0 },
1272 /* 0xcb */ { NULL, NULL, 0 },
1273 /* 0xcc */ { NULL, NULL, 0 },
1274 /* 0xcd */ { NULL, NULL, 0 },
1275 /* 0xce */ { NULL, NULL, 0 },
1276 /* 0xcf */ { NULL, NULL, 0 },
1277 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1278 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1279 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1280 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1281 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1282 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1283 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1284 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1285 /* 0xd8 */ { NULL, NULL, 0 },
1286 /* 0xd9 */ { NULL, NULL, 0 },
1287 /* 0xda */ { NULL, NULL, 0 },
1288 /* 0xdb */ { NULL, NULL, 0 },
1289 /* 0xdc */ { NULL, NULL, 0 },
1290 /* 0xdd */ { NULL, NULL, 0 },
1291 /* 0xde */ { NULL, NULL, 0 },
1292 /* 0xdf */ { NULL, NULL, 0 },
1293 /* 0xe0 */ { NULL, NULL, 0 },
1294 /* 0xe1 */ { NULL, NULL, 0 },
1295 /* 0xe2 */ { NULL, NULL, 0 },
1296 /* 0xe3 */ { NULL, NULL, 0 },
1297 /* 0xe4 */ { NULL, NULL, 0 },
1298 /* 0xe5 */ { NULL, NULL, 0 },
1299 /* 0xe6 */ { NULL, NULL, 0 },
1300 /* 0xe7 */ { NULL, NULL, 0 },
1301 /* 0xe8 */ { NULL, NULL, 0 },
1302 /* 0xe9 */ { NULL, NULL, 0 },
1303 /* 0xea */ { NULL, NULL, 0 },
1304 /* 0xeb */ { NULL, NULL, 0 },
1305 /* 0xec */ { NULL, NULL, 0 },
1306 /* 0xed */ { NULL, NULL, 0 },
1307 /* 0xee */ { NULL, NULL, 0 },
1308 /* 0xef */ { NULL, NULL, 0 },
1309 /* 0xf0 */ { NULL, NULL, 0 },
1310 /* 0xf1 */ { NULL, NULL, 0 },
1311 /* 0xf2 */ { NULL, NULL, 0 },
1312 /* 0xf3 */ { NULL, NULL, 0 },
1313 /* 0xf4 */ { NULL, NULL, 0 },
1314 /* 0xf5 */ { NULL, NULL, 0 },
1315 /* 0xf6 */ { NULL, NULL, 0 },
1316 /* 0xf7 */ { NULL, NULL, 0 },
1317 /* 0xf8 */ { NULL, NULL, 0 },
1318 /* 0xf9 */ { NULL, NULL, 0 },
1319 /* 0xfa */ { NULL, NULL, 0 },
1320 /* 0xfb */ { NULL, NULL, 0 },
1321 /* 0xfc */ { NULL, NULL, 0 },
1322 /* 0xfd */ { NULL, NULL, 0 },
1323 /* 0xfe */ { NULL, NULL, 0 },
1324 /* 0xff */ { NULL, NULL, 0 }
1328 /*******************************************************************
1329 allocate and initialize a reply packet
1330 ********************************************************************/
1332 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1333 const char *inbuf, char **outbuf, uint8_t num_words,
1334 uint32_t num_bytes)
1337 * Protect against integer wrap
1339 if ((num_bytes > 0xffffff)
1340 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1341 char *msg;
1342 if (asprintf(&msg, "num_bytes too large: %u",
1343 (unsigned)num_bytes) == -1) {
1344 msg = CONST_DISCARD(char *, "num_bytes too large");
1346 smb_panic(msg);
1349 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1350 smb_size + num_words*2 + num_bytes);
1351 if (*outbuf == NULL) {
1352 return false;
1355 construct_reply_common(req, inbuf, *outbuf);
1356 srv_set_message(*outbuf, num_words, num_bytes, false);
1358 * Zero out the word area, the caller has to take care of the bcc area
1359 * himself
1361 if (num_words != 0) {
1362 memset(*outbuf + smb_vwv0, 0, num_words*2);
1365 return true;
1368 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1370 char *outbuf;
1371 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1372 num_bytes)) {
1373 smb_panic("could not allocate output buffer\n");
1375 req->outbuf = (uint8_t *)outbuf;
1379 /*******************************************************************
1380 Dump a packet to a file.
1381 ********************************************************************/
1383 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1385 int fd, i;
1386 char *fname = NULL;
1387 if (DEBUGLEVEL < 50) {
1388 return;
1391 if (len < 4) len = smb_len(data)+4;
1392 for (i=1;i<100;i++) {
1393 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1394 type ? "req" : "resp") == -1) {
1395 return;
1397 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1398 if (fd != -1 || errno != EEXIST) break;
1400 if (fd != -1) {
1401 ssize_t ret = write(fd, data, len);
1402 if (ret != len)
1403 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1404 close(fd);
1405 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1407 SAFE_FREE(fname);
1410 /****************************************************************************
1411 Prepare everything for calling the actual request function, and potentially
1412 call the request function via the "new" interface.
1414 Return False if the "legacy" function needs to be called, everything is
1415 prepared.
1417 Return True if we're done.
1419 I know this API sucks, but it is the one with the least code change I could
1420 find.
1421 ****************************************************************************/
1423 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1425 int flags;
1426 uint16 session_tag;
1427 connection_struct *conn = NULL;
1428 struct smbd_server_connection *sconn = req->sconn;
1430 errno = 0;
1432 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1433 * so subtract 4 from it. */
1434 if (!valid_smb_header(req->inbuf)
1435 || (size < (smb_size - 4))) {
1436 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1437 smb_len(req->inbuf)));
1438 exit_server_cleanly("Non-SMB packet");
1441 if (smb_messages[type].fn == NULL) {
1442 DEBUG(0,("Unknown message type %d!\n",type));
1443 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1444 reply_unknown_new(req, type);
1445 return NULL;
1448 flags = smb_messages[type].flags;
1450 /* In share mode security we must ignore the vuid. */
1451 session_tag = (lp_security() == SEC_SHARE)
1452 ? UID_FIELD_INVALID : req->vuid;
1453 conn = req->conn;
1455 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1456 (int)sys_getpid(), (unsigned long)conn));
1458 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1460 /* Ensure this value is replaced in the incoming packet. */
1461 SSVAL(req->inbuf,smb_uid,session_tag);
1464 * Ensure the correct username is in current_user_info. This is a
1465 * really ugly bugfix for problems with multiple session_setup_and_X's
1466 * being done and allowing %U and %G substitutions to work correctly.
1467 * There is a reason this code is done here, don't move it unless you
1468 * know what you're doing... :-).
1469 * JRA.
1472 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1473 user_struct *vuser = NULL;
1475 sconn->smb1.sessions.last_session_tag = session_tag;
1476 if(session_tag != UID_FIELD_INVALID) {
1477 vuser = get_valid_user_struct(sconn, session_tag);
1478 if (vuser) {
1479 set_current_user_info(
1480 vuser->session_info->sanitized_username,
1481 vuser->session_info->unix_name,
1482 vuser->session_info->info3->base.domain.string);
1487 /* Does this call need to be run as the connected user? */
1488 if (flags & AS_USER) {
1490 /* Does this call need a valid tree connection? */
1491 if (!conn) {
1493 * Amazingly, the error code depends on the command
1494 * (from Samba4).
1496 if (type == SMBntcreateX) {
1497 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1498 } else {
1499 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1501 return NULL;
1504 if (!change_to_user(conn,session_tag)) {
1505 DEBUG(0, ("Error: Could not change to user. Removing "
1506 "deferred open, mid=%llu.\n",
1507 (unsigned long long)req->mid));
1508 reply_force_doserror(req, ERRSRV, ERRbaduid);
1509 return conn;
1512 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1514 /* Does it need write permission? */
1515 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1516 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1517 return conn;
1520 /* IPC services are limited */
1521 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1522 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1523 return conn;
1525 } else {
1526 /* This call needs to be run as root */
1527 change_to_root_user();
1530 /* load service specific parameters */
1531 if (conn) {
1532 if (req->encrypted) {
1533 conn->encrypted_tid = true;
1534 /* encrypted required from now on. */
1535 conn->encrypt_level = Required;
1536 } else if (ENCRYPTION_REQUIRED(conn)) {
1537 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1538 exit_server_cleanly("encryption required "
1539 "on connection");
1540 return conn;
1544 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1545 (flags & (AS_USER|DO_CHDIR)
1546 ?True:False))) {
1547 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1548 return conn;
1550 conn->num_smb_operations++;
1553 /* does this protocol need to be run as guest? */
1554 if ((flags & AS_GUEST)
1555 && (!change_to_guest() ||
1556 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1557 sconn->client_id.name,
1558 sconn->client_id.addr))) {
1559 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1560 return conn;
1563 smb_messages[type].fn(req);
1564 return req->conn;
1567 /****************************************************************************
1568 Construct a reply to the incoming packet.
1569 ****************************************************************************/
1571 static void construct_reply(struct smbd_server_connection *sconn,
1572 char *inbuf, int size, size_t unread_bytes,
1573 uint32_t seqnum, bool encrypted,
1574 struct smb_perfcount_data *deferred_pcd)
1576 connection_struct *conn;
1577 struct smb_request *req;
1579 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1580 smb_panic("could not allocate smb_request");
1583 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1584 encrypted, seqnum)) {
1585 exit_server_cleanly("Invalid SMB request");
1588 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1590 /* we popped this message off the queue - keep original perf data */
1591 if (deferred_pcd)
1592 req->pcd = *deferred_pcd;
1593 else {
1594 SMB_PERFCOUNT_START(&req->pcd);
1595 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1596 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1599 conn = switch_message(req->cmd, req, size);
1601 if (req->unread_bytes) {
1602 /* writeX failed. drain socket. */
1603 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1604 req->unread_bytes) {
1605 smb_panic("failed to drain pending bytes");
1607 req->unread_bytes = 0;
1610 if (req->done) {
1611 TALLOC_FREE(req);
1612 return;
1615 if (req->outbuf == NULL) {
1616 return;
1619 if (CVAL(req->outbuf,0) == 0) {
1620 show_msg((char *)req->outbuf);
1623 if (!srv_send_smb(req->sconn,
1624 (char *)req->outbuf,
1625 true, req->seqnum+1,
1626 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1627 &req->pcd)) {
1628 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1631 TALLOC_FREE(req);
1633 return;
1636 /****************************************************************************
1637 Process an smb from the client
1638 ****************************************************************************/
1639 static void process_smb(struct smbd_server_connection *sconn,
1640 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1641 uint32_t seqnum, bool encrypted,
1642 struct smb_perfcount_data *deferred_pcd)
1644 int msg_type = CVAL(inbuf,0);
1646 DO_PROFILE_INC(smb_count);
1648 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1649 smb_len(inbuf) ) );
1650 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1651 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1653 if (msg_type != 0) {
1655 * NetBIOS session request, keepalive, etc.
1657 reply_special(sconn, (char *)inbuf, nread);
1658 goto done;
1661 if (sconn->using_smb2) {
1662 /* At this point we're not really using smb2,
1663 * we make the decision here.. */
1664 if (smbd_is_smb2_header(inbuf, nread)) {
1665 smbd_smb2_first_negprot(sconn, inbuf, nread);
1666 return;
1667 } else if (nread >= smb_size && valid_smb_header(inbuf)
1668 && CVAL(inbuf, smb_com) != 0x72) {
1669 /* This is a non-negprot SMB1 packet.
1670 Disable SMB2 from now on. */
1671 sconn->using_smb2 = false;
1675 show_msg((char *)inbuf);
1677 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1678 encrypted, deferred_pcd);
1679 sconn->trans_num++;
1681 done:
1682 sconn->smb1.num_requests++;
1684 /* The timeout_processing function isn't run nearly
1685 often enough to implement 'max log size' without
1686 overrunning the size of the file by many megabytes.
1687 This is especially true if we are running at debug
1688 level 10. Checking every 50 SMBs is a nice
1689 tradeoff of performance vs log file size overrun. */
1691 if ((sconn->smb1.num_requests % 50) == 0 &&
1692 need_to_check_log_size()) {
1693 change_to_root_user();
1694 check_log_size();
1698 /****************************************************************************
1699 Return a string containing the function name of a SMB command.
1700 ****************************************************************************/
1702 const char *smb_fn_name(int type)
1704 const char *unknown_name = "SMBunknown";
1706 if (smb_messages[type].name == NULL)
1707 return(unknown_name);
1709 return(smb_messages[type].name);
1712 /****************************************************************************
1713 Helper functions for contruct_reply.
1714 ****************************************************************************/
1716 void add_to_common_flags2(uint32 v)
1718 common_flags2 |= v;
1721 void remove_from_common_flags2(uint32 v)
1723 common_flags2 &= ~v;
1726 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1727 char *outbuf)
1729 srv_set_message(outbuf,0,0,false);
1731 SCVAL(outbuf, smb_com, req->cmd);
1732 SIVAL(outbuf,smb_rcls,0);
1733 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1734 SSVAL(outbuf,smb_flg2,
1735 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1736 common_flags2);
1737 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1739 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1740 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1741 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1742 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1745 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1747 construct_reply_common(req, (char *)req->inbuf, outbuf);
1751 * How many bytes have we already accumulated up to the current wct field
1752 * offset?
1755 size_t req_wct_ofs(struct smb_request *req)
1757 size_t buf_size;
1759 if (req->chain_outbuf == NULL) {
1760 return smb_wct - 4;
1762 buf_size = talloc_get_size(req->chain_outbuf);
1763 if ((buf_size % 4) != 0) {
1764 buf_size += (4 - (buf_size % 4));
1766 return buf_size - 4;
1770 * Hack around reply_nterror & friends not being aware of chained requests,
1771 * generating illegal (i.e. wct==0) chain replies.
1774 static void fixup_chain_error_packet(struct smb_request *req)
1776 uint8_t *outbuf = req->outbuf;
1777 req->outbuf = NULL;
1778 reply_outbuf(req, 2, 0);
1779 memcpy(req->outbuf, outbuf, smb_wct);
1780 TALLOC_FREE(outbuf);
1781 SCVAL(req->outbuf, smb_vwv0, 0xff);
1785 * @brief Find the smb_cmd offset of the last command pushed
1786 * @param[in] buf The buffer we're building up
1787 * @retval Where can we put our next andx cmd?
1789 * While chaining requests, the "next" request we're looking at needs to put
1790 * its SMB_Command before the data the previous request already built up added
1791 * to the chain. Find the offset to the place where we have to put our cmd.
1794 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1796 uint8_t cmd;
1797 size_t ofs;
1799 cmd = CVAL(buf, smb_com);
1801 SMB_ASSERT(is_andx_req(cmd));
1803 ofs = smb_vwv0;
1805 while (CVAL(buf, ofs) != 0xff) {
1807 if (!is_andx_req(CVAL(buf, ofs))) {
1808 return false;
1812 * ofs is from start of smb header, so add the 4 length
1813 * bytes. The next cmd is right after the wct field.
1815 ofs = SVAL(buf, ofs+2) + 4 + 1;
1817 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1820 *pofs = ofs;
1821 return true;
1825 * @brief Do the smb chaining at a buffer level
1826 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1827 * @param[in] smb_command The command that we want to issue
1828 * @param[in] wct How many words?
1829 * @param[in] vwv The words, already in network order
1830 * @param[in] bytes_alignment How shall we align "bytes"?
1831 * @param[in] num_bytes How many bytes?
1832 * @param[in] bytes The data the request ships
1834 * smb_splice_chain() adds the vwv and bytes to the request already present in
1835 * *poutbuf.
1838 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1839 uint8_t wct, const uint16_t *vwv,
1840 size_t bytes_alignment,
1841 uint32_t num_bytes, const uint8_t *bytes)
1843 uint8_t *outbuf;
1844 size_t old_size, new_size;
1845 size_t ofs;
1846 size_t chain_padding = 0;
1847 size_t bytes_padding = 0;
1848 bool first_request;
1850 old_size = talloc_get_size(*poutbuf);
1853 * old_size == smb_wct means we're pushing the first request in for
1854 * libsmb/
1857 first_request = (old_size == smb_wct);
1859 if (!first_request && ((old_size % 4) != 0)) {
1861 * Align the wct field of subsequent requests to a 4-byte
1862 * boundary
1864 chain_padding = 4 - (old_size % 4);
1868 * After the old request comes the new wct field (1 byte), the vwv's
1869 * and the num_bytes field. After at we might need to align the bytes
1870 * given to us to "bytes_alignment", increasing the num_bytes value.
1873 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1875 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1876 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1879 new_size += bytes_padding + num_bytes;
1881 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1882 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1883 (unsigned)new_size));
1884 return false;
1887 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1888 if (outbuf == NULL) {
1889 DEBUG(0, ("talloc failed\n"));
1890 return false;
1892 *poutbuf = outbuf;
1894 if (first_request) {
1895 SCVAL(outbuf, smb_com, smb_command);
1896 } else {
1897 size_t andx_cmd_ofs;
1899 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1900 DEBUG(1, ("invalid command chain\n"));
1901 *poutbuf = TALLOC_REALLOC_ARRAY(
1902 NULL, *poutbuf, uint8_t, old_size);
1903 return false;
1906 if (chain_padding != 0) {
1907 memset(outbuf + old_size, 0, chain_padding);
1908 old_size += chain_padding;
1911 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1912 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1915 ofs = old_size;
1918 * Push the chained request:
1920 * wct field
1923 SCVAL(outbuf, ofs, wct);
1924 ofs += 1;
1927 * vwv array
1930 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1931 ofs += sizeof(uint16_t) * wct;
1934 * bcc (byte count)
1937 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1938 ofs += sizeof(uint16_t);
1941 * padding
1944 if (bytes_padding != 0) {
1945 memset(outbuf + ofs, 0, bytes_padding);
1946 ofs += bytes_padding;
1950 * The bytes field
1953 memcpy(outbuf + ofs, bytes, num_bytes);
1955 return true;
1958 /****************************************************************************
1959 Construct a chained reply and add it to the already made reply
1960 ****************************************************************************/
1962 void chain_reply(struct smb_request *req)
1964 size_t smblen = smb_len(req->inbuf);
1965 size_t already_used, length_needed;
1966 uint8_t chain_cmd;
1967 uint32_t chain_offset; /* uint32_t to avoid overflow */
1969 uint8_t wct;
1970 uint16_t *vwv;
1971 uint16_t buflen;
1972 uint8_t *buf;
1974 if (IVAL(req->outbuf, smb_rcls) != 0) {
1975 fixup_chain_error_packet(req);
1979 * Any of the AndX requests and replies have at least a wct of
1980 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1981 * beginning of the SMB header to the next wct field.
1983 * None of the AndX requests put anything valuable in vwv[0] and [1],
1984 * so we can overwrite it here to form the chain.
1987 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1988 if (req->chain_outbuf == NULL) {
1989 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1990 req, req->outbuf, uint8_t,
1991 smb_len(req->outbuf) + 4);
1992 if (req->chain_outbuf == NULL) {
1993 smb_panic("talloc failed");
1996 req->outbuf = NULL;
1997 goto error;
2001 * Here we assume that this is the end of the chain. For that we need
2002 * to set "next command" to 0xff and the offset to 0. If we later find
2003 * more commands in the chain, this will be overwritten again.
2006 SCVAL(req->outbuf, smb_vwv0, 0xff);
2007 SCVAL(req->outbuf, smb_vwv0+1, 0);
2008 SSVAL(req->outbuf, smb_vwv1, 0);
2010 if (req->chain_outbuf == NULL) {
2012 * In req->chain_outbuf we collect all the replies. Start the
2013 * chain by copying in the first reply.
2015 * We do the realloc because later on we depend on
2016 * talloc_get_size to determine the length of
2017 * chain_outbuf. The reply_xxx routines might have
2018 * over-allocated (reply_pipe_read_and_X used to be such an
2019 * example).
2021 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2022 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2023 if (req->chain_outbuf == NULL) {
2024 smb_panic("talloc failed");
2026 req->outbuf = NULL;
2027 } else {
2029 * Update smb headers where subsequent chained commands
2030 * may have updated them.
2032 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2033 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2035 if (!smb_splice_chain(&req->chain_outbuf,
2036 CVAL(req->outbuf, smb_com),
2037 CVAL(req->outbuf, smb_wct),
2038 (uint16_t *)(req->outbuf + smb_vwv),
2039 0, smb_buflen(req->outbuf),
2040 (uint8_t *)smb_buf(req->outbuf))) {
2041 goto error;
2043 TALLOC_FREE(req->outbuf);
2047 * We use the old request's vwv field to grab the next chained command
2048 * and offset into the chained fields.
2051 chain_cmd = CVAL(req->vwv+0, 0);
2052 chain_offset = SVAL(req->vwv+1, 0);
2054 if (chain_cmd == 0xff) {
2056 * End of chain, no more requests from the client. So ship the
2057 * replies.
2059 smb_setlen((char *)(req->chain_outbuf),
2060 talloc_get_size(req->chain_outbuf) - 4);
2062 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2063 true, req->seqnum+1,
2064 IS_CONN_ENCRYPTED(req->conn)
2065 ||req->encrypted,
2066 &req->pcd)) {
2067 exit_server_cleanly("chain_reply: srv_send_smb "
2068 "failed.");
2070 TALLOC_FREE(req->chain_outbuf);
2071 req->done = true;
2072 return;
2075 /* add a new perfcounter for this element of chain */
2076 SMB_PERFCOUNT_ADD(&req->pcd);
2077 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2078 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2081 * Check if the client tries to fool us. The request so far uses the
2082 * space to the end of the byte buffer in the request just
2083 * processed. The chain_offset can't point into that area. If that was
2084 * the case, we could end up with an endless processing of the chain,
2085 * we would always handle the same request.
2088 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2089 if (chain_offset < already_used) {
2090 goto error;
2094 * Next check: Make sure the chain offset does not point beyond the
2095 * overall smb request length.
2098 length_needed = chain_offset+1; /* wct */
2099 if (length_needed > smblen) {
2100 goto error;
2104 * Now comes the pointer magic. Goal here is to set up req->vwv and
2105 * req->buf correctly again to be able to call the subsequent
2106 * switch_message(). The chain offset (the former vwv[1]) points at
2107 * the new wct field.
2110 wct = CVAL(smb_base(req->inbuf), chain_offset);
2113 * Next consistency check: Make the new vwv array fits in the overall
2114 * smb request.
2117 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2118 if (length_needed > smblen) {
2119 goto error;
2121 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2124 * Now grab the new byte buffer....
2127 buflen = SVAL(vwv+wct, 0);
2130 * .. and check that it fits.
2133 length_needed += buflen;
2134 if (length_needed > smblen) {
2135 goto error;
2137 buf = (uint8_t *)(vwv+wct+1);
2139 req->cmd = chain_cmd;
2140 req->wct = wct;
2141 req->vwv = vwv;
2142 req->buflen = buflen;
2143 req->buf = buf;
2145 switch_message(chain_cmd, req, smblen);
2147 if (req->outbuf == NULL) {
2149 * This happens if the chained command has suspended itself or
2150 * if it has called srv_send_smb() itself.
2152 return;
2156 * We end up here if the chained command was not itself chained or
2157 * suspended, but for example a close() command. We now need to splice
2158 * the chained commands' outbuf into the already built up chain_outbuf
2159 * and ship the result.
2161 goto done;
2163 error:
2165 * We end up here if there's any error in the chain syntax. Report a
2166 * DOS error, just like Windows does.
2168 reply_force_doserror(req, ERRSRV, ERRerror);
2169 fixup_chain_error_packet(req);
2171 done:
2173 * This scary statement intends to set the
2174 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2175 * to the value req->outbuf carries
2177 SSVAL(req->chain_outbuf, smb_flg2,
2178 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2179 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2182 * Transfer the error codes from the subrequest to the main one
2184 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2185 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2187 if (!smb_splice_chain(&req->chain_outbuf,
2188 CVAL(req->outbuf, smb_com),
2189 CVAL(req->outbuf, smb_wct),
2190 (uint16_t *)(req->outbuf + smb_vwv),
2191 0, smb_buflen(req->outbuf),
2192 (uint8_t *)smb_buf(req->outbuf))) {
2193 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2195 TALLOC_FREE(req->outbuf);
2197 smb_setlen((char *)(req->chain_outbuf),
2198 talloc_get_size(req->chain_outbuf) - 4);
2200 show_msg((char *)(req->chain_outbuf));
2202 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2203 true, req->seqnum+1,
2204 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2205 &req->pcd)) {
2206 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2208 TALLOC_FREE(req->chain_outbuf);
2209 req->done = true;
2212 /****************************************************************************
2213 Check if services need reloading.
2214 ****************************************************************************/
2216 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2219 if (last_smb_conf_reload_time == 0) {
2220 last_smb_conf_reload_time = t;
2223 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2224 reload_services(sconn->msg_ctx, sconn->sock, True);
2225 last_smb_conf_reload_time = t;
2229 static bool fd_is_readable(int fd)
2231 int ret, revents;
2233 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2235 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2239 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2241 /* TODO: make write nonblocking */
2244 static void smbd_server_connection_read_handler(
2245 struct smbd_server_connection *conn, int fd)
2247 uint8_t *inbuf = NULL;
2248 size_t inbuf_len = 0;
2249 size_t unread_bytes = 0;
2250 bool encrypted = false;
2251 TALLOC_CTX *mem_ctx = talloc_tos();
2252 NTSTATUS status;
2253 uint32_t seqnum;
2255 bool from_client = (conn->sock == fd);
2257 if (from_client) {
2258 smbd_lock_socket(conn);
2260 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2261 DEBUG(10,("the echo listener was faster\n"));
2262 smbd_unlock_socket(conn);
2263 return;
2266 /* TODO: make this completely nonblocking */
2267 status = receive_smb_talloc(mem_ctx, conn,
2268 (char **)(void *)&inbuf,
2269 0, /* timeout */
2270 &unread_bytes,
2271 &encrypted,
2272 &inbuf_len, &seqnum,
2273 false /* trusted channel */);
2274 smbd_unlock_socket(conn);
2275 } else {
2276 /* TODO: make this completely nonblocking */
2277 status = receive_smb_talloc(mem_ctx, conn,
2278 (char **)(void *)&inbuf,
2279 0, /* timeout */
2280 &unread_bytes,
2281 &encrypted,
2282 &inbuf_len, &seqnum,
2283 true /* trusted channel */);
2286 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2287 goto process;
2289 if (NT_STATUS_IS_ERR(status)) {
2290 exit_server_cleanly("failed to receive smb request");
2292 if (!NT_STATUS_IS_OK(status)) {
2293 return;
2296 process:
2297 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2298 seqnum, encrypted, NULL);
2301 static void smbd_server_connection_handler(struct event_context *ev,
2302 struct fd_event *fde,
2303 uint16_t flags,
2304 void *private_data)
2306 struct smbd_server_connection *conn = talloc_get_type(private_data,
2307 struct smbd_server_connection);
2309 if (flags & EVENT_FD_WRITE) {
2310 smbd_server_connection_write_handler(conn);
2311 return;
2313 if (flags & EVENT_FD_READ) {
2314 smbd_server_connection_read_handler(conn, conn->sock);
2315 return;
2319 static void smbd_server_echo_handler(struct event_context *ev,
2320 struct fd_event *fde,
2321 uint16_t flags,
2322 void *private_data)
2324 struct smbd_server_connection *conn = talloc_get_type(private_data,
2325 struct smbd_server_connection);
2327 if (flags & EVENT_FD_WRITE) {
2328 smbd_server_connection_write_handler(conn);
2329 return;
2331 if (flags & EVENT_FD_READ) {
2332 smbd_server_connection_read_handler(
2333 conn, conn->smb1.echo_handler.trusted_fd);
2334 return;
2338 /****************************************************************************
2339 received when we should release a specific IP
2340 ****************************************************************************/
2341 static void release_ip(const char *ip, void *priv)
2343 const char *addr = (const char *)priv;
2344 const char *p = addr;
2346 if (strncmp("::ffff:", addr, 7) == 0) {
2347 p = addr + 7;
2350 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2351 /* we can't afford to do a clean exit - that involves
2352 database writes, which would potentially mean we
2353 are still running after the failover has finished -
2354 we have to get rid of this process ID straight
2355 away */
2356 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2357 ip));
2358 /* note we must exit with non-zero status so the unclean handler gets
2359 called in the parent, so that the brl database is tickled */
2360 _exit(1);
2364 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2365 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2367 struct smbd_server_connection *sconn = talloc_get_type_abort(
2368 private_data, struct smbd_server_connection);
2370 release_ip((char *)data->data, sconn->client_id.addr);
2373 #ifdef CLUSTER_SUPPORT
2374 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2375 struct sockaddr_storage *client)
2377 socklen_t length;
2378 length = sizeof(*server);
2379 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2380 return -1;
2382 length = sizeof(*client);
2383 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2384 return -1;
2386 return 0;
2388 #endif
2391 * Send keepalive packets to our client
2393 static bool keepalive_fn(const struct timeval *now, void *private_data)
2395 struct smbd_server_connection *sconn = smbd_server_conn;
2396 bool ret;
2398 if (sconn->using_smb2) {
2399 /* Don't do keepalives on an SMB2 connection. */
2400 return false;
2403 smbd_lock_socket(smbd_server_conn);
2404 ret = send_keepalive(sconn->sock);
2405 smbd_unlock_socket(smbd_server_conn);
2407 if (!ret) {
2408 char addr[INET6_ADDRSTRLEN];
2410 * Try and give an error message saying what
2411 * client failed.
2413 DEBUG(0, ("send_keepalive failed for client %s. "
2414 "Error %s - exiting\n",
2415 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2416 strerror(errno)));
2417 return False;
2419 return True;
2423 * Do the recurring check if we're idle
2425 static bool deadtime_fn(const struct timeval *now, void *private_data)
2427 struct smbd_server_connection *sconn =
2428 (struct smbd_server_connection *)private_data;
2430 if ((conn_num_open(sconn) == 0)
2431 || (conn_idle_all(sconn, now->tv_sec))) {
2432 DEBUG( 2, ( "Closing idle connection\n" ) );
2433 messaging_send(sconn->msg_ctx,
2434 messaging_server_id(sconn->msg_ctx),
2435 MSG_SHUTDOWN, &data_blob_null);
2436 return False;
2439 return True;
2443 * Do the recurring log file and smb.conf reload checks.
2446 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2448 struct smbd_server_connection *sconn = talloc_get_type_abort(
2449 private_data, struct smbd_server_connection);
2451 DEBUG(5, ("housekeeping\n"));
2453 change_to_root_user();
2455 /* update printer queue caches if necessary */
2456 update_monitored_printq_cache(sconn->msg_ctx);
2458 /* check if we need to reload services */
2459 check_reload(sconn, time_mono(NULL));
2461 /* Change machine password if neccessary. */
2462 attempt_machine_password_change();
2465 * Force a log file check.
2467 force_check_log_size();
2468 check_log_size();
2469 return true;
2472 static int create_unlink_tmp(const char *dir)
2474 char *fname;
2475 int fd;
2477 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2478 if (fname == NULL) {
2479 errno = ENOMEM;
2480 return -1;
2482 fd = mkstemp(fname);
2483 if (fd == -1) {
2484 TALLOC_FREE(fname);
2485 return -1;
2487 if (unlink(fname) == -1) {
2488 int sys_errno = errno;
2489 close(fd);
2490 TALLOC_FREE(fname);
2491 errno = sys_errno;
2492 return -1;
2494 TALLOC_FREE(fname);
2495 return fd;
2498 struct smbd_echo_state {
2499 struct tevent_context *ev;
2500 struct iovec *pending;
2501 struct smbd_server_connection *sconn;
2502 int parent_pipe;
2504 struct tevent_fd *parent_fde;
2506 struct tevent_fd *read_fde;
2507 struct tevent_req *write_req;
2510 static void smbd_echo_writer_done(struct tevent_req *req);
2512 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2514 int num_pending;
2516 if (state->write_req != NULL) {
2517 return;
2520 num_pending = talloc_array_length(state->pending);
2521 if (num_pending == 0) {
2522 return;
2525 state->write_req = writev_send(state, state->ev, NULL,
2526 state->parent_pipe, false,
2527 state->pending, num_pending);
2528 if (state->write_req == NULL) {
2529 DEBUG(1, ("writev_send failed\n"));
2530 exit(1);
2533 talloc_steal(state->write_req, state->pending);
2534 state->pending = NULL;
2536 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2537 state);
2540 static void smbd_echo_writer_done(struct tevent_req *req)
2542 struct smbd_echo_state *state = tevent_req_callback_data(
2543 req, struct smbd_echo_state);
2544 ssize_t written;
2545 int err;
2547 written = writev_recv(req, &err);
2548 TALLOC_FREE(req);
2549 state->write_req = NULL;
2550 if (written == -1) {
2551 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2552 exit(1);
2554 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2555 smbd_echo_activate_writer(state);
2558 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2559 uint32_t seqnum)
2561 struct smb_request req;
2562 uint16_t num_replies;
2563 size_t out_len;
2564 char *outbuf;
2565 bool ok;
2567 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2568 DEBUG(10, ("Got netbios keepalive\n"));
2570 * Just swallow it
2572 return true;
2575 if (inbuf_len < smb_size) {
2576 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2577 return false;
2579 if (!valid_smb_header(inbuf)) {
2580 DEBUG(10, ("Got invalid SMB header\n"));
2581 return false;
2584 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2585 seqnum)) {
2586 return false;
2588 req.inbuf = inbuf;
2590 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2591 smb_messages[req.cmd].name
2592 ? smb_messages[req.cmd].name : "unknown"));
2594 if (req.cmd != SMBecho) {
2595 return false;
2597 if (req.wct < 1) {
2598 return false;
2601 num_replies = SVAL(req.vwv+0, 0);
2602 if (num_replies != 1) {
2603 /* Not a Windows "Hey, you're still there?" request */
2604 return false;
2607 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2608 1, req.buflen)) {
2609 DEBUG(10, ("create_outbuf failed\n"));
2610 return false;
2612 req.outbuf = (uint8_t *)outbuf;
2614 SSVAL(req.outbuf, smb_vwv0, num_replies);
2616 if (req.buflen > 0) {
2617 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2620 out_len = smb_len(req.outbuf) + 4;
2622 ok = srv_send_smb(req.sconn,
2623 (char *)outbuf,
2624 true, seqnum+1,
2625 false, &req.pcd);
2626 TALLOC_FREE(outbuf);
2627 if (!ok) {
2628 exit(1);
2631 return true;
2634 static void smbd_echo_exit(struct tevent_context *ev,
2635 struct tevent_fd *fde, uint16_t flags,
2636 void *private_data)
2638 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2639 exit(0);
2642 static void smbd_echo_reader(struct tevent_context *ev,
2643 struct tevent_fd *fde, uint16_t flags,
2644 void *private_data)
2646 struct smbd_echo_state *state = talloc_get_type_abort(
2647 private_data, struct smbd_echo_state);
2648 struct smbd_server_connection *sconn = state->sconn;
2649 size_t unread, num_pending;
2650 NTSTATUS status;
2651 struct iovec *tmp;
2652 size_t iov_len;
2653 uint32_t seqnum = 0;
2654 bool reply;
2655 bool ok;
2656 bool encrypted = false;
2658 smb_msleep(1000);
2660 ok = smbd_lock_socket_internal(sconn);
2661 if (!ok) {
2662 DEBUG(0, ("%s: failed to lock socket\n",
2663 __location__));
2664 exit(1);
2667 if (!fd_is_readable(sconn->sock)) {
2668 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2669 (int)sys_getpid()));
2670 ok = smbd_unlock_socket_internal(sconn);
2671 if (!ok) {
2672 DEBUG(1, ("%s: failed to unlock socket in\n",
2673 __location__));
2674 exit(1);
2676 return;
2679 num_pending = talloc_array_length(state->pending);
2680 tmp = talloc_realloc(state, state->pending, struct iovec,
2681 num_pending+1);
2682 if (tmp == NULL) {
2683 DEBUG(1, ("talloc_realloc failed\n"));
2684 exit(1);
2686 state->pending = tmp;
2688 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2690 status = receive_smb_talloc(state->pending, sconn,
2691 (char **)(void *)&state->pending[num_pending].iov_base,
2692 0 /* timeout */,
2693 &unread,
2694 &encrypted,
2695 &iov_len,
2696 &seqnum,
2697 false /* trusted_channel*/);
2698 if (!NT_STATUS_IS_OK(status)) {
2699 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2700 (int)sys_getpid(), nt_errstr(status)));
2701 exit(1);
2703 state->pending[num_pending].iov_len = iov_len;
2705 ok = smbd_unlock_socket_internal(sconn);
2706 if (!ok) {
2707 DEBUG(1, ("%s: failed to unlock socket in\n",
2708 __location__));
2709 exit(1);
2712 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2713 state->pending[num_pending].iov_len,
2714 seqnum);
2715 if (reply) {
2716 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2717 /* no check, shrinking by some bytes does not fail */
2718 state->pending = talloc_realloc(state, state->pending,
2719 struct iovec,
2720 num_pending);
2721 return;
2724 if (state->pending[num_pending].iov_len >= smb_size) {
2726 * place the seqnum in the packet so that the main process
2727 * can reply with signing
2729 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2730 smb_ss_field, seqnum);
2731 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2732 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2735 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2736 smbd_echo_activate_writer(state);
2739 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2740 int parent_pipe)
2742 struct smbd_echo_state *state;
2744 state = talloc_zero(sconn, struct smbd_echo_state);
2745 if (state == NULL) {
2746 DEBUG(1, ("talloc failed\n"));
2747 return;
2749 state->sconn = sconn;
2750 state->parent_pipe = parent_pipe;
2751 state->ev = s3_tevent_context_init(state);
2752 if (state->ev == NULL) {
2753 DEBUG(1, ("tevent_context_init failed\n"));
2754 TALLOC_FREE(state);
2755 return;
2757 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2758 TEVENT_FD_READ, smbd_echo_exit,
2759 state);
2760 if (state->parent_fde == NULL) {
2761 DEBUG(1, ("tevent_add_fd failed\n"));
2762 TALLOC_FREE(state);
2763 return;
2765 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2766 TEVENT_FD_READ, smbd_echo_reader,
2767 state);
2768 if (state->read_fde == NULL) {
2769 DEBUG(1, ("tevent_add_fd failed\n"));
2770 TALLOC_FREE(state);
2771 return;
2774 while (true) {
2775 if (tevent_loop_once(state->ev) == -1) {
2776 DEBUG(1, ("tevent_loop_once failed: %s\n",
2777 strerror(errno)));
2778 break;
2781 TALLOC_FREE(state);
2785 * Handle SMBecho requests in a forked child process
2787 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2789 int listener_pipe[2];
2790 int res;
2791 pid_t child;
2793 res = pipe(listener_pipe);
2794 if (res == -1) {
2795 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2796 return false;
2798 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2799 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2800 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2801 goto fail;
2804 child = sys_fork();
2805 if (child == 0) {
2806 NTSTATUS status;
2808 close(listener_pipe[0]);
2809 set_blocking(listener_pipe[1], false);
2811 status = reinit_after_fork(sconn->msg_ctx,
2812 smbd_event_context(),
2813 procid_self(), false);
2814 if (!NT_STATUS_IS_OK(status)) {
2815 DEBUG(1, ("reinit_after_fork failed: %s\n",
2816 nt_errstr(status)));
2817 exit(1);
2819 smbd_echo_loop(sconn, listener_pipe[1]);
2820 exit(0);
2822 close(listener_pipe[1]);
2823 listener_pipe[1] = -1;
2824 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2826 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2829 * Without smb signing this is the same as the normal smbd
2830 * listener. This needs to change once signing comes in.
2832 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2833 sconn,
2834 sconn->smb1.echo_handler.trusted_fd,
2835 EVENT_FD_READ,
2836 smbd_server_echo_handler,
2837 sconn);
2838 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2839 DEBUG(1, ("event_add_fd failed\n"));
2840 goto fail;
2843 return true;
2845 fail:
2846 if (listener_pipe[0] != -1) {
2847 close(listener_pipe[0]);
2849 if (listener_pipe[1] != -1) {
2850 close(listener_pipe[1]);
2852 sconn->smb1.echo_handler.trusted_fd = -1;
2853 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2854 close(sconn->smb1.echo_handler.socket_lock_fd);
2856 sconn->smb1.echo_handler.trusted_fd = -1;
2857 sconn->smb1.echo_handler.socket_lock_fd = -1;
2858 return false;
2861 #if CLUSTER_SUPPORT
2863 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2864 struct sockaddr_storage *srv,
2865 struct sockaddr_storage *clnt)
2867 struct ctdbd_connection *cconn;
2868 char tmp_addr[INET6_ADDRSTRLEN];
2869 char *addr;
2871 cconn = messaging_ctdbd_connection();
2872 if (cconn == NULL) {
2873 return NT_STATUS_NO_MEMORY;
2876 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2877 addr = talloc_strdup(cconn, tmp_addr);
2878 if (addr == NULL) {
2879 return NT_STATUS_NO_MEMORY;
2881 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2884 #endif
2886 /****************************************************************************
2887 Process commands from the client
2888 ****************************************************************************/
2890 void smbd_process(struct smbd_server_connection *sconn)
2892 TALLOC_CTX *frame = talloc_stackframe();
2893 struct sockaddr_storage ss;
2894 struct sockaddr *sa = NULL;
2895 socklen_t sa_socklen;
2896 struct tsocket_address *local_address = NULL;
2897 struct tsocket_address *remote_address = NULL;
2898 const char *remaddr = NULL;
2899 int ret;
2901 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2902 !lp_async_smb_echo_handler()) {
2904 * We're not making the desion here,
2905 * we're just allowing the client
2906 * to decide between SMB1 and SMB2
2907 * with the first negprot
2908 * packet.
2910 sconn->using_smb2 = true;
2913 /* Ensure child is set to blocking mode */
2914 set_blocking(sconn->sock,True);
2916 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2917 set_socket_options(sconn->sock, lp_socket_options());
2919 sa = (struct sockaddr *)(void *)&ss;
2920 sa_socklen = sizeof(ss);
2921 ret = getpeername(sconn->sock, sa, &sa_socklen);
2922 if (ret != 0) {
2923 int level = (errno == ENOTCONN)?2:0;
2924 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2925 exit_server_cleanly("getpeername() failed.\n");
2927 ret = tsocket_address_bsd_from_sockaddr(sconn,
2928 sa, sa_socklen,
2929 &remote_address);
2930 if (ret != 0) {
2931 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2932 __location__, strerror(errno)));
2933 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2936 sa = (struct sockaddr *)(void *)&ss;
2937 sa_socklen = sizeof(ss);
2938 ret = getsockname(sconn->sock, sa, &sa_socklen);
2939 if (ret != 0) {
2940 int level = (errno == ENOTCONN)?2:0;
2941 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2942 exit_server_cleanly("getsockname() failed.\n");
2944 ret = tsocket_address_bsd_from_sockaddr(sconn,
2945 sa, sa_socklen,
2946 &local_address);
2947 if (ret != 0) {
2948 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2949 __location__, strerror(errno)));
2950 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2953 sconn->local_address = local_address;
2954 sconn->remote_address = remote_address;
2956 if (tsocket_address_is_inet(remote_address, "ip")) {
2957 remaddr = tsocket_address_inet_addr_string(
2958 sconn->remote_address,
2959 talloc_tos());
2960 if (remaddr == NULL) {
2963 } else {
2964 remaddr = "0.0.0.0";
2967 /* this is needed so that we get decent entries
2968 in smbstatus for port 445 connects */
2969 set_remote_machine_name(remaddr, false);
2970 reload_services(sconn->msg_ctx, sconn->sock, true);
2973 * Before the first packet, check the global hosts allow/ hosts deny
2974 * parameters before doing any parsing of packets passed to us by the
2975 * client. This prevents attacks on our parsing code from hosts not in
2976 * the hosts allow list.
2979 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2980 sconn->client_id.name,
2981 sconn->client_id.addr)) {
2983 * send a negative session response "not listening on calling
2984 * name"
2986 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2987 DEBUG( 1, ("Connection denied from %s to %s\n",
2988 tsocket_address_string(remote_address, talloc_tos()),
2989 tsocket_address_string(local_address, talloc_tos())));
2990 (void)srv_send_smb(sconn,(char *)buf, false,
2991 0, false, NULL);
2992 exit_server_cleanly("connection denied");
2995 DEBUG(10, ("Connection allowed from %s to %s\n",
2996 tsocket_address_string(remote_address, talloc_tos()),
2997 tsocket_address_string(local_address, talloc_tos())));
2999 init_modules();
3001 smb_perfcount_init();
3003 if (!init_account_policy()) {
3004 exit_server("Could not open account policy tdb.\n");
3007 if (*lp_rootdir()) {
3008 if (chroot(lp_rootdir()) != 0) {
3009 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3010 exit_server("Failed to chroot()");
3012 if (chdir("/") == -1) {
3013 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3014 exit_server("Failed to chroot()");
3016 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3019 if (!srv_init_signing(sconn)) {
3020 exit_server("Failed to init smb_signing");
3023 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3024 exit_server("Failed to fork echo handler");
3027 /* Setup oplocks */
3028 if (!init_oplocks(sconn->msg_ctx))
3029 exit_server("Failed to init oplocks");
3031 /* register our message handlers */
3032 messaging_register(sconn->msg_ctx, NULL,
3033 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3034 messaging_register(sconn->msg_ctx, sconn,
3035 MSG_SMB_RELEASE_IP, msg_release_ip);
3036 messaging_register(sconn->msg_ctx, NULL,
3037 MSG_SMB_CLOSE_FILE, msg_close_file);
3040 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3041 * MSGs to all child processes
3043 messaging_deregister(sconn->msg_ctx,
3044 MSG_DEBUG, NULL);
3045 messaging_register(sconn->msg_ctx, NULL,
3046 MSG_DEBUG, debug_message);
3048 if ((lp_keepalive() != 0)
3049 && !(event_add_idle(smbd_event_context(), NULL,
3050 timeval_set(lp_keepalive(), 0),
3051 "keepalive", keepalive_fn,
3052 NULL))) {
3053 DEBUG(0, ("Could not add keepalive event\n"));
3054 exit(1);
3057 if (!(event_add_idle(smbd_event_context(), NULL,
3058 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3059 "deadtime", deadtime_fn, sconn))) {
3060 DEBUG(0, ("Could not add deadtime event\n"));
3061 exit(1);
3064 if (!(event_add_idle(smbd_event_context(), NULL,
3065 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3066 "housekeeping", housekeeping_fn, sconn))) {
3067 DEBUG(0, ("Could not add housekeeping event\n"));
3068 exit(1);
3071 #ifdef CLUSTER_SUPPORT
3073 if (lp_clustering()) {
3075 * We need to tell ctdb about our client's TCP
3076 * connection, so that for failover ctdbd can send
3077 * tickle acks, triggering a reconnection by the
3078 * client.
3081 struct sockaddr_storage srv, clnt;
3083 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3084 NTSTATUS status;
3085 status = smbd_register_ips(sconn, &srv, &clnt);
3086 if (!NT_STATUS_IS_OK(status)) {
3087 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3088 nt_errstr(status)));
3090 } else
3092 DEBUG(0,("Unable to get tcp info for "
3093 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3094 strerror(errno)));
3098 #endif
3100 sconn->nbt.got_session = false;
3102 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3104 sconn->smb1.sessions.done_sesssetup = false;
3105 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3106 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3107 /* users from session setup */
3108 sconn->smb1.sessions.session_userlist = NULL;
3109 /* workgroup from session setup. */
3110 sconn->smb1.sessions.session_workgroup = NULL;
3111 /* this holds info on user ids that are already validated for this VC */
3112 sconn->smb1.sessions.validated_users = NULL;
3113 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3114 sconn->smb1.sessions.num_validated_vuids = 0;
3116 conn_init(sconn);
3117 if (!init_dptrs(sconn)) {
3118 exit_server("init_dptrs() failed");
3121 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3122 sconn,
3123 sconn->sock,
3124 EVENT_FD_READ,
3125 smbd_server_connection_handler,
3126 sconn);
3127 if (!sconn->smb1.fde) {
3128 exit_server("failed to create smbd_server_connection fde");
3131 TALLOC_FREE(frame);
3133 while (True) {
3134 NTSTATUS status;
3136 frame = talloc_stackframe_pool(8192);
3138 errno = 0;
3140 status = smbd_server_connection_loop_once(sconn);
3141 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3142 !NT_STATUS_IS_OK(status)) {
3143 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3144 " exiting\n", nt_errstr(status)));
3145 break;
3148 TALLOC_FREE(frame);
3151 exit_server_cleanly(NULL);
3154 bool req_is_in_chain(struct smb_request *req)
3156 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3158 * We're right now handling a subsequent request, so we must
3159 * be in a chain
3161 return true;
3164 if (!is_andx_req(req->cmd)) {
3165 return false;
3168 if (req->wct < 2) {
3170 * Okay, an illegal request, but definitely not chained :-)
3172 return false;
3175 return (CVAL(req->vwv+0, 0) != 0xFF);