dnsp: Parse TXT records
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blob8d36dd3c89ff1971672f6069267bea03aacb2b91
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 "smbd/globals.h"
23 #include "librpc/gen_ndr/netlogon.h"
24 #include "librpc/gen_ndr/messaging.h"
25 #include "../lib/async_req/async_sock.h"
26 #include "ctdbd_conn.h"
27 #include "../lib/util/select.h"
29 extern bool global_machine_password_needs_changing;
31 static void construct_reply_common(struct smb_request *req, const char *inbuf,
32 char *outbuf);
33 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
35 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
37 bool ok;
39 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
40 return true;
43 sconn->smb1.echo_handler.ref_count++;
45 if (sconn->smb1.echo_handler.ref_count > 1) {
46 return true;
49 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
51 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
52 SMB_F_SETLKW, 0, 0, F_WRLCK);
53 if (!ok) {
54 return false;
57 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
59 return true;
62 void smbd_lock_socket(struct smbd_server_connection *sconn)
64 if (!smbd_lock_socket_internal(sconn)) {
65 exit_server_cleanly("failed to lock socket");
69 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
71 bool ok;
73 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
74 return true;
77 sconn->smb1.echo_handler.ref_count--;
79 if (sconn->smb1.echo_handler.ref_count > 0) {
80 return true;
83 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
84 SMB_F_SETLKW, 0, 0, F_UNLCK);
85 if (!ok) {
86 return false;
89 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
91 return true;
94 void smbd_unlock_socket(struct smbd_server_connection *sconn)
96 if (!smbd_unlock_socket_internal(sconn)) {
97 exit_server_cleanly("failed to unlock socket");
101 /* Accessor function for smb_read_error for smbd functions. */
103 /****************************************************************************
104 Send an smb to a fd.
105 ****************************************************************************/
107 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
108 bool do_signing, uint32_t seqnum,
109 bool do_encrypt,
110 struct smb_perfcount_data *pcd)
112 size_t len = 0;
113 size_t nwritten=0;
114 ssize_t ret;
115 char *buf_out = buffer;
117 smbd_lock_socket(sconn);
119 if (do_signing) {
120 /* Sign the outgoing packet if required. */
121 srv_calculate_sign_mac(sconn, buf_out, seqnum);
124 if (do_encrypt) {
125 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
126 if (!NT_STATUS_IS_OK(status)) {
127 DEBUG(0, ("send_smb: SMB encryption failed "
128 "on outgoing packet! Error %s\n",
129 nt_errstr(status) ));
130 goto out;
134 len = smb_len(buf_out) + 4;
136 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
137 if (ret <= 0) {
139 char addr[INET6_ADDRSTRLEN];
141 * Try and give an error message saying what
142 * client failed.
144 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
145 (int)sys_getpid(), (int)len,
146 get_peer_addr(sconn->sock, addr, sizeof(addr)),
147 (int)ret, strerror(errno) ));
149 srv_free_enc_buffer(buf_out);
150 goto out;
153 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
154 srv_free_enc_buffer(buf_out);
155 out:
156 SMB_PERFCOUNT_END(pcd);
158 smbd_unlock_socket(sconn);
159 return true;
162 /*******************************************************************
163 Setup the word count and byte count for a smb message.
164 ********************************************************************/
166 int srv_set_message(char *buf,
167 int num_words,
168 int num_bytes,
169 bool zero)
171 if (zero && (num_words || num_bytes)) {
172 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
174 SCVAL(buf,smb_wct,num_words);
175 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
176 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
177 return (smb_size + num_words*2 + num_bytes);
180 static bool valid_smb_header(const uint8_t *inbuf)
182 if (is_encrypted_packet(inbuf)) {
183 return true;
186 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
187 * but it just looks weird to call strncmp for this one.
189 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
192 /* Socket functions for smbd packet processing. */
194 static bool valid_packet_size(size_t len)
197 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
198 * of header. Don't print the error if this fits.... JRA.
201 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
202 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
203 (unsigned long)len));
204 return false;
206 return true;
209 static NTSTATUS read_packet_remainder(int fd, char *buffer,
210 unsigned int timeout, ssize_t len)
212 NTSTATUS status;
214 if (len <= 0) {
215 return NT_STATUS_OK;
218 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
219 if (!NT_STATUS_IS_OK(status)) {
220 char addr[INET6_ADDRSTRLEN];
221 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
222 "error = %s.\n",
223 get_peer_addr(fd, addr, sizeof(addr)),
224 nt_errstr(status)));
226 return status;
229 /****************************************************************************
230 Attempt a zerocopy writeX read. We know here that len > smb_size-4
231 ****************************************************************************/
234 * Unfortunately, earlier versions of smbclient/libsmbclient
235 * don't send this "standard" writeX header. I've fixed this
236 * for 3.2 but we'll use the old method with earlier versions.
237 * Windows and CIFSFS at least use this standard size. Not
238 * sure about MacOSX.
241 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
242 (2*14) + /* word count (including bcc) */ \
243 1 /* pad byte */)
245 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
246 const char lenbuf[4],
247 int fd, char **buffer,
248 unsigned int timeout,
249 size_t *p_unread,
250 size_t *len_ret)
252 /* Size of a WRITEX call (+4 byte len). */
253 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
254 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
255 ssize_t toread;
256 NTSTATUS status;
258 memcpy(writeX_header, lenbuf, 4);
260 status = read_fd_with_timeout(
261 fd, writeX_header + 4,
262 STANDARD_WRITE_AND_X_HEADER_SIZE,
263 STANDARD_WRITE_AND_X_HEADER_SIZE,
264 timeout, NULL);
266 if (!NT_STATUS_IS_OK(status)) {
267 char addr[INET6_ADDRSTRLEN];
268 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
269 "error = %s.\n",
270 get_peer_addr(fd, addr, sizeof(addr)),
271 nt_errstr(status)));
272 return status;
276 * Ok - now try and see if this is a possible
277 * valid writeX call.
280 if (is_valid_writeX_buffer(smbd_server_conn,
281 (uint8_t *)writeX_header)) {
283 * If the data offset is beyond what
284 * we've read, drain the extra bytes.
286 uint16_t doff = SVAL(writeX_header,smb_vwv11);
287 ssize_t newlen;
289 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
290 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
291 if (drain_socket(fd, drain) != drain) {
292 smb_panic("receive_smb_raw_talloc_partial_read:"
293 " failed to drain pending bytes");
295 } else {
296 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
299 /* Spoof down the length and null out the bcc. */
300 set_message_bcc(writeX_header, 0);
301 newlen = smb_len(writeX_header);
303 /* Copy the header we've written. */
305 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
306 writeX_header,
307 sizeof(writeX_header));
309 if (*buffer == NULL) {
310 DEBUG(0, ("Could not allocate inbuf of length %d\n",
311 (int)sizeof(writeX_header)));
312 return NT_STATUS_NO_MEMORY;
315 /* Work out the remaining bytes. */
316 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
317 *len_ret = newlen + 4;
318 return NT_STATUS_OK;
321 if (!valid_packet_size(len)) {
322 return NT_STATUS_INVALID_PARAMETER;
326 * Not a valid writeX call. Just do the standard
327 * talloc and return.
330 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
332 if (*buffer == NULL) {
333 DEBUG(0, ("Could not allocate inbuf of length %d\n",
334 (int)len+4));
335 return NT_STATUS_NO_MEMORY;
338 /* Copy in what we already read. */
339 memcpy(*buffer,
340 writeX_header,
341 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
342 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
344 if(toread > 0) {
345 status = read_packet_remainder(
346 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
347 timeout, toread);
349 if (!NT_STATUS_IS_OK(status)) {
350 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
351 nt_errstr(status)));
352 return status;
356 *len_ret = len + 4;
357 return NT_STATUS_OK;
360 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
361 char **buffer, unsigned int timeout,
362 size_t *p_unread, size_t *plen)
364 char lenbuf[4];
365 size_t len;
366 int min_recv_size = lp_min_receive_file_size();
367 NTSTATUS status;
369 *p_unread = 0;
371 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
372 if (!NT_STATUS_IS_OK(status)) {
373 return status;
376 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
377 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
378 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
379 !srv_is_signing_active(smbd_server_conn) &&
380 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
382 return receive_smb_raw_talloc_partial_read(
383 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
386 if (!valid_packet_size(len)) {
387 return NT_STATUS_INVALID_PARAMETER;
391 * The +4 here can't wrap, we've checked the length above already.
394 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
396 if (*buffer == NULL) {
397 DEBUG(0, ("Could not allocate inbuf of length %d\n",
398 (int)len+4));
399 return NT_STATUS_NO_MEMORY;
402 memcpy(*buffer, lenbuf, sizeof(lenbuf));
404 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
405 if (!NT_STATUS_IS_OK(status)) {
406 return status;
409 *plen = len + 4;
410 return NT_STATUS_OK;
413 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
414 char **buffer, unsigned int timeout,
415 size_t *p_unread, bool *p_encrypted,
416 size_t *p_len,
417 uint32_t *seqnum,
418 bool trusted_channel)
420 size_t len = 0;
421 NTSTATUS status;
423 *p_encrypted = false;
425 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
426 p_unread, &len);
427 if (!NT_STATUS_IS_OK(status)) {
428 char addr[INET6_ADDRSTRLEN];
429 DEBUG(1, ("read_smb_length_return_keepalive failed for "
430 "client %s read error = %s.\n",
431 get_peer_addr(fd, addr, sizeof(addr)),
432 nt_errstr(status)));
433 return status;
436 if (is_encrypted_packet((uint8_t *)*buffer)) {
437 status = srv_decrypt_buffer(*buffer);
438 if (!NT_STATUS_IS_OK(status)) {
439 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
440 "incoming packet! Error %s\n",
441 nt_errstr(status) ));
442 return status;
444 *p_encrypted = true;
447 /* Check the incoming SMB signature. */
448 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
449 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
450 "incoming packet!\n"));
451 return NT_STATUS_INVALID_NETWORK_RESPONSE;
454 *p_len = len;
455 return NT_STATUS_OK;
459 * Initialize a struct smb_request from an inbuf
462 static bool init_smb_request(struct smb_request *req,
463 struct smbd_server_connection *sconn,
464 const uint8 *inbuf,
465 size_t unread_bytes, bool encrypted,
466 uint32_t seqnum)
468 size_t req_size = smb_len(inbuf) + 4;
469 /* Ensure we have at least smb_size bytes. */
470 if (req_size < smb_size) {
471 DEBUG(0,("init_smb_request: invalid request size %u\n",
472 (unsigned int)req_size ));
473 return false;
475 req->cmd = CVAL(inbuf, smb_com);
476 req->flags2 = SVAL(inbuf, smb_flg2);
477 req->smbpid = SVAL(inbuf, smb_pid);
478 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
479 req->seqnum = seqnum;
480 req->vuid = SVAL(inbuf, smb_uid);
481 req->tid = SVAL(inbuf, smb_tid);
482 req->wct = CVAL(inbuf, smb_wct);
483 req->vwv = (uint16_t *)(inbuf+smb_vwv);
484 req->buflen = smb_buflen(inbuf);
485 req->buf = (const uint8_t *)smb_buf(inbuf);
486 req->unread_bytes = unread_bytes;
487 req->encrypted = encrypted;
488 req->sconn = sconn;
489 req->conn = conn_find(sconn,req->tid);
490 req->chain_fsp = NULL;
491 req->chain_outbuf = NULL;
492 req->done = false;
493 req->smb2req = NULL;
494 smb_init_perfcount_data(&req->pcd);
496 /* Ensure we have at least wct words and 2 bytes of bcc. */
497 if (smb_size + req->wct*2 > req_size) {
498 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
499 (unsigned int)req->wct,
500 (unsigned int)req_size));
501 return false;
503 /* Ensure bcc is correct. */
504 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
505 DEBUG(0,("init_smb_request: invalid bcc number %u "
506 "(wct = %u, size %u)\n",
507 (unsigned int)req->buflen,
508 (unsigned int)req->wct,
509 (unsigned int)req_size));
510 return false;
513 req->outbuf = NULL;
514 return true;
517 static void process_smb(struct smbd_server_connection *conn,
518 uint8_t *inbuf, size_t nread, size_t unread_bytes,
519 uint32_t seqnum, bool encrypted,
520 struct smb_perfcount_data *deferred_pcd);
522 static void smbd_deferred_open_timer(struct event_context *ev,
523 struct timed_event *te,
524 struct timeval _tval,
525 void *private_data)
527 struct pending_message_list *msg = talloc_get_type(private_data,
528 struct pending_message_list);
529 TALLOC_CTX *mem_ctx = talloc_tos();
530 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
531 uint8_t *inbuf;
533 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
534 msg->buf.length);
535 if (inbuf == NULL) {
536 exit_server("smbd_deferred_open_timer: talloc failed\n");
537 return;
540 /* We leave this message on the queue so the open code can
541 know this is a retry. */
542 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
543 (unsigned long long)mid ));
545 /* Mark the message as processed so this is not
546 * re-processed in error. */
547 msg->processed = true;
549 process_smb(smbd_server_conn, inbuf,
550 msg->buf.length, 0,
551 msg->seqnum, msg->encrypted, &msg->pcd);
553 /* If it's still there and was processed, remove it. */
554 msg = get_deferred_open_message_smb(mid);
555 if (msg && msg->processed) {
556 remove_deferred_open_message_smb(mid);
560 /****************************************************************************
561 Function to push a message onto the tail of a linked list of smb messages ready
562 for processing.
563 ****************************************************************************/
565 static bool push_queued_message(struct smb_request *req,
566 struct timeval request_time,
567 struct timeval end_time,
568 char *private_data, size_t private_len)
570 int msg_len = smb_len(req->inbuf) + 4;
571 struct pending_message_list *msg;
573 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
575 if(msg == NULL) {
576 DEBUG(0,("push_message: malloc fail (1)\n"));
577 return False;
580 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
581 if(msg->buf.data == NULL) {
582 DEBUG(0,("push_message: malloc fail (2)\n"));
583 TALLOC_FREE(msg);
584 return False;
587 msg->request_time = request_time;
588 msg->seqnum = req->seqnum;
589 msg->encrypted = req->encrypted;
590 msg->processed = false;
591 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
593 if (private_data) {
594 msg->private_data = data_blob_talloc(msg, private_data,
595 private_len);
596 if (msg->private_data.data == NULL) {
597 DEBUG(0,("push_message: malloc fail (3)\n"));
598 TALLOC_FREE(msg);
599 return False;
603 msg->te = event_add_timed(smbd_event_context(),
604 msg,
605 end_time,
606 smbd_deferred_open_timer,
607 msg);
608 if (!msg->te) {
609 DEBUG(0,("push_message: event_add_timed failed\n"));
610 TALLOC_FREE(msg);
611 return false;
614 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
616 DEBUG(10,("push_message: pushed message length %u on "
617 "deferred_open_queue\n", (unsigned int)msg_len));
619 return True;
622 /****************************************************************************
623 Function to delete a sharing violation open message by mid.
624 ****************************************************************************/
626 void remove_deferred_open_message_smb(uint64_t mid)
628 struct pending_message_list *pml;
630 if (smbd_server_conn->using_smb2) {
631 remove_deferred_open_message_smb2(smbd_server_conn, mid);
632 return;
635 for (pml = deferred_open_queue; pml; pml = pml->next) {
636 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
637 DEBUG(10,("remove_deferred_open_message_smb: "
638 "deleting mid %llu len %u\n",
639 (unsigned long long)mid,
640 (unsigned int)pml->buf.length ));
641 DLIST_REMOVE(deferred_open_queue, pml);
642 TALLOC_FREE(pml);
643 return;
648 /****************************************************************************
649 Move a sharing violation open retry message to the front of the list and
650 schedule it for immediate processing.
651 ****************************************************************************/
653 void schedule_deferred_open_message_smb(uint64_t mid)
655 struct pending_message_list *pml;
656 int i = 0;
658 if (smbd_server_conn->using_smb2) {
659 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
660 return;
663 for (pml = deferred_open_queue; pml; pml = pml->next) {
664 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
666 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
667 "msg_mid = %llu\n",
668 i++,
669 (unsigned long long)msg_mid ));
671 if (mid == msg_mid) {
672 struct timed_event *te;
674 if (pml->processed) {
675 /* A processed message should not be
676 * rescheduled. */
677 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
678 "message mid %llu was already processed\n",
679 (unsigned long long)msg_mid ));
680 continue;
683 DEBUG(10,("schedule_deferred_open_message_smb: "
684 "scheduling mid %llu\n",
685 (unsigned long long)mid ));
687 te = event_add_timed(smbd_event_context(),
688 pml,
689 timeval_zero(),
690 smbd_deferred_open_timer,
691 pml);
692 if (!te) {
693 DEBUG(10,("schedule_deferred_open_message_smb: "
694 "event_add_timed() failed, "
695 "skipping mid %llu\n",
696 (unsigned long long)msg_mid ));
699 TALLOC_FREE(pml->te);
700 pml->te = te;
701 DLIST_PROMOTE(deferred_open_queue, pml);
702 return;
706 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
707 "find message mid %llu\n",
708 (unsigned long long)mid ));
711 /****************************************************************************
712 Return true if this mid is on the deferred queue and was not yet processed.
713 ****************************************************************************/
715 bool open_was_deferred(uint64_t mid)
717 struct pending_message_list *pml;
719 if (smbd_server_conn->using_smb2) {
720 return open_was_deferred_smb2(smbd_server_conn, mid);
723 for (pml = deferred_open_queue; pml; pml = pml->next) {
724 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
725 return True;
728 return False;
731 /****************************************************************************
732 Return the message queued by this mid.
733 ****************************************************************************/
735 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
737 struct pending_message_list *pml;
739 for (pml = deferred_open_queue; pml; pml = pml->next) {
740 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
741 return pml;
744 return NULL;
747 /****************************************************************************
748 Get the state data queued by this mid.
749 ****************************************************************************/
751 bool get_deferred_open_message_state(struct smb_request *smbreq,
752 struct timeval *p_request_time,
753 void **pp_state)
755 struct pending_message_list *pml;
757 if (smbd_server_conn->using_smb2) {
758 return get_deferred_open_message_state_smb2(smbreq->smb2req,
759 p_request_time,
760 pp_state);
763 pml = get_deferred_open_message_smb(smbreq->mid);
764 if (!pml) {
765 return false;
767 if (p_request_time) {
768 *p_request_time = pml->request_time;
770 if (pp_state) {
771 *pp_state = (void *)pml->private_data.data;
773 return true;
776 /****************************************************************************
777 Function to push a deferred open smb message onto a linked list of local smb
778 messages ready for processing.
779 ****************************************************************************/
781 bool push_deferred_open_message_smb(struct smb_request *req,
782 struct timeval request_time,
783 struct timeval timeout,
784 struct file_id id,
785 char *private_data, size_t priv_len)
787 struct timeval end_time;
789 if (req->smb2req) {
790 return push_deferred_open_message_smb2(req->smb2req,
791 request_time,
792 timeout,
794 private_data,
795 priv_len);
798 if (req->unread_bytes) {
799 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
800 "unread_bytes = %u\n",
801 (unsigned int)req->unread_bytes ));
802 smb_panic("push_deferred_open_message_smb: "
803 "logic error unread_bytes != 0" );
806 end_time = timeval_sum(&request_time, &timeout);
808 DEBUG(10,("push_deferred_open_message_smb: pushing message "
809 "len %u mid %llu timeout time [%u.%06u]\n",
810 (unsigned int) smb_len(req->inbuf)+4,
811 (unsigned long long)req->mid,
812 (unsigned int)end_time.tv_sec,
813 (unsigned int)end_time.tv_usec));
815 return push_queued_message(req, request_time, end_time,
816 private_data, priv_len);
819 struct idle_event {
820 struct timed_event *te;
821 struct timeval interval;
822 char *name;
823 bool (*handler)(const struct timeval *now, void *private_data);
824 void *private_data;
827 static void smbd_idle_event_handler(struct event_context *ctx,
828 struct timed_event *te,
829 struct timeval now,
830 void *private_data)
832 struct idle_event *event =
833 talloc_get_type_abort(private_data, struct idle_event);
835 TALLOC_FREE(event->te);
837 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
838 event->name, event->te));
840 if (!event->handler(&now, event->private_data)) {
841 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
842 event->name, event->te));
843 /* Don't repeat, delete ourselves */
844 TALLOC_FREE(event);
845 return;
848 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
849 event->name, event->te));
851 event->te = event_add_timed(ctx, event,
852 timeval_sum(&now, &event->interval),
853 smbd_idle_event_handler, event);
855 /* We can't do much but fail here. */
856 SMB_ASSERT(event->te != NULL);
859 struct idle_event *event_add_idle(struct event_context *event_ctx,
860 TALLOC_CTX *mem_ctx,
861 struct timeval interval,
862 const char *name,
863 bool (*handler)(const struct timeval *now,
864 void *private_data),
865 void *private_data)
867 struct idle_event *result;
868 struct timeval now = timeval_current();
870 result = TALLOC_P(mem_ctx, struct idle_event);
871 if (result == NULL) {
872 DEBUG(0, ("talloc failed\n"));
873 return NULL;
876 result->interval = interval;
877 result->handler = handler;
878 result->private_data = private_data;
880 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
881 DEBUG(0, ("talloc failed\n"));
882 TALLOC_FREE(result);
883 return NULL;
886 result->te = event_add_timed(event_ctx, result,
887 timeval_sum(&now, &interval),
888 smbd_idle_event_handler, result);
889 if (result->te == NULL) {
890 DEBUG(0, ("event_add_timed failed\n"));
891 TALLOC_FREE(result);
892 return NULL;
895 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
896 return result;
899 static void smbd_sig_term_handler(struct tevent_context *ev,
900 struct tevent_signal *se,
901 int signum,
902 int count,
903 void *siginfo,
904 void *private_data)
906 exit_server_cleanly("termination signal");
909 void smbd_setup_sig_term_handler(void)
911 struct tevent_signal *se;
913 se = tevent_add_signal(smbd_event_context(),
914 smbd_event_context(),
915 SIGTERM, 0,
916 smbd_sig_term_handler,
917 NULL);
918 if (!se) {
919 exit_server("failed to setup SIGTERM handler");
923 static void smbd_sig_hup_handler(struct tevent_context *ev,
924 struct tevent_signal *se,
925 int signum,
926 int count,
927 void *siginfo,
928 void *private_data)
930 struct messaging_context *msg_ctx = talloc_get_type_abort(
931 private_data, struct messaging_context);
932 change_to_root_user();
933 DEBUG(1,("Reloading services after SIGHUP\n"));
934 reload_services(msg_ctx, smbd_server_conn->sock, False);
937 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
938 struct messaging_context *msg_ctx)
940 struct tevent_signal *se;
942 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
943 msg_ctx);
944 if (!se) {
945 exit_server("failed to setup SIGHUP handler");
949 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
951 fd_set r_fds, w_fds;
952 int selrtn = 0;
953 struct timeval to;
954 int maxfd = 0;
956 to.tv_sec = SMBD_SELECT_TIMEOUT;
957 to.tv_usec = 0;
960 * Setup the select fd sets.
963 FD_ZERO(&r_fds);
964 FD_ZERO(&w_fds);
967 * Are there any timed events waiting ? If so, ensure we don't
968 * select for longer than it would take to wait for them.
972 struct timeval now;
973 GetTimeOfDay(&now);
975 event_add_to_select_args(smbd_event_context(), &now,
976 &r_fds, &w_fds, &to, &maxfd);
979 /* Process a signal and timed events now... */
980 if (run_events(smbd_event_context(), &selrtn, NULL, NULL)) {
981 return NT_STATUS_RETRY;
985 int sav;
986 START_PROFILE(smbd_idle);
988 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
989 sav = errno;
991 END_PROFILE(smbd_idle);
992 errno = sav;
995 /* Check if error */
996 if (selrtn == -1) {
997 if (errno == EINTR)
998 return NT_STATUS_RETRY;
999 else
1000 /* Maybe the socket is dead? */
1001 return map_nt_error_from_unix(errno);
1004 /* Process events until all available fds have been handled.
1005 * This allows for fair round-robin handling of all available fds
1006 * on each select() wakeup, while still maintaining responsiveness
1007 * by re-checking for signal and timed events between the handling
1008 * of each ready fd. */
1009 do {
1010 run_events(smbd_event_context(), &selrtn, &r_fds, &w_fds);
1011 } while (selrtn > 0);
1013 /* Processed all fds or timed out */
1014 if (selrtn == 0) {
1015 return NT_STATUS_RETRY;
1018 /* should not be reached */
1019 return NT_STATUS_INTERNAL_ERROR;
1023 * Only allow 5 outstanding trans requests. We're allocating memory, so
1024 * prevent a DoS.
1027 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1029 int count = 0;
1030 for (; list != NULL; list = list->next) {
1032 if (list->mid == mid) {
1033 return NT_STATUS_INVALID_PARAMETER;
1036 count += 1;
1038 if (count > 5) {
1039 return NT_STATUS_INSUFFICIENT_RESOURCES;
1042 return NT_STATUS_OK;
1046 These flags determine some of the permissions required to do an operation
1048 Note that I don't set NEED_WRITE on some write operations because they
1049 are used by some brain-dead clients when printing, and I don't want to
1050 force write permissions on print services.
1052 #define AS_USER (1<<0)
1053 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1054 #define TIME_INIT (1<<2)
1055 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1056 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1057 #define DO_CHDIR (1<<6)
1060 define a list of possible SMB messages and their corresponding
1061 functions. Any message that has a NULL function is unimplemented -
1062 please feel free to contribute implementations!
1064 static const struct smb_message_struct {
1065 const char *name;
1066 void (*fn)(struct smb_request *req);
1067 int flags;
1068 } smb_messages[256] = {
1070 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1071 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1072 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1073 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1074 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1075 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1076 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1077 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1078 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1079 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1080 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1081 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1082 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1083 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1084 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1085 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1086 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1087 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1088 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1089 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1090 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1091 /* 0x15 */ { NULL, NULL, 0 },
1092 /* 0x16 */ { NULL, NULL, 0 },
1093 /* 0x17 */ { NULL, NULL, 0 },
1094 /* 0x18 */ { NULL, NULL, 0 },
1095 /* 0x19 */ { NULL, NULL, 0 },
1096 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1097 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1098 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1099 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1100 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1101 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1102 /* 0x20 */ { "SMBwritec", NULL,0},
1103 /* 0x21 */ { NULL, NULL, 0 },
1104 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1105 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1106 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1107 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1108 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1109 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1110 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1111 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1112 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1113 /* 0x2b */ { "SMBecho",reply_echo,0},
1114 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1115 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1116 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1117 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1118 /* 0x30 */ { NULL, NULL, 0 },
1119 /* 0x31 */ { NULL, NULL, 0 },
1120 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1121 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1122 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1123 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1124 /* 0x36 */ { NULL, NULL, 0 },
1125 /* 0x37 */ { NULL, NULL, 0 },
1126 /* 0x38 */ { NULL, NULL, 0 },
1127 /* 0x39 */ { NULL, NULL, 0 },
1128 /* 0x3a */ { NULL, NULL, 0 },
1129 /* 0x3b */ { NULL, NULL, 0 },
1130 /* 0x3c */ { NULL, NULL, 0 },
1131 /* 0x3d */ { NULL, NULL, 0 },
1132 /* 0x3e */ { NULL, NULL, 0 },
1133 /* 0x3f */ { NULL, NULL, 0 },
1134 /* 0x40 */ { NULL, NULL, 0 },
1135 /* 0x41 */ { NULL, NULL, 0 },
1136 /* 0x42 */ { NULL, NULL, 0 },
1137 /* 0x43 */ { NULL, NULL, 0 },
1138 /* 0x44 */ { NULL, NULL, 0 },
1139 /* 0x45 */ { NULL, NULL, 0 },
1140 /* 0x46 */ { NULL, NULL, 0 },
1141 /* 0x47 */ { NULL, NULL, 0 },
1142 /* 0x48 */ { NULL, NULL, 0 },
1143 /* 0x49 */ { NULL, NULL, 0 },
1144 /* 0x4a */ { NULL, NULL, 0 },
1145 /* 0x4b */ { NULL, NULL, 0 },
1146 /* 0x4c */ { NULL, NULL, 0 },
1147 /* 0x4d */ { NULL, NULL, 0 },
1148 /* 0x4e */ { NULL, NULL, 0 },
1149 /* 0x4f */ { NULL, NULL, 0 },
1150 /* 0x50 */ { NULL, NULL, 0 },
1151 /* 0x51 */ { NULL, NULL, 0 },
1152 /* 0x52 */ { NULL, NULL, 0 },
1153 /* 0x53 */ { NULL, NULL, 0 },
1154 /* 0x54 */ { NULL, NULL, 0 },
1155 /* 0x55 */ { NULL, NULL, 0 },
1156 /* 0x56 */ { NULL, NULL, 0 },
1157 /* 0x57 */ { NULL, NULL, 0 },
1158 /* 0x58 */ { NULL, NULL, 0 },
1159 /* 0x59 */ { NULL, NULL, 0 },
1160 /* 0x5a */ { NULL, NULL, 0 },
1161 /* 0x5b */ { NULL, NULL, 0 },
1162 /* 0x5c */ { NULL, NULL, 0 },
1163 /* 0x5d */ { NULL, NULL, 0 },
1164 /* 0x5e */ { NULL, NULL, 0 },
1165 /* 0x5f */ { NULL, NULL, 0 },
1166 /* 0x60 */ { NULL, NULL, 0 },
1167 /* 0x61 */ { NULL, NULL, 0 },
1168 /* 0x62 */ { NULL, NULL, 0 },
1169 /* 0x63 */ { NULL, NULL, 0 },
1170 /* 0x64 */ { NULL, NULL, 0 },
1171 /* 0x65 */ { NULL, NULL, 0 },
1172 /* 0x66 */ { NULL, NULL, 0 },
1173 /* 0x67 */ { NULL, NULL, 0 },
1174 /* 0x68 */ { NULL, NULL, 0 },
1175 /* 0x69 */ { NULL, NULL, 0 },
1176 /* 0x6a */ { NULL, NULL, 0 },
1177 /* 0x6b */ { NULL, NULL, 0 },
1178 /* 0x6c */ { NULL, NULL, 0 },
1179 /* 0x6d */ { NULL, NULL, 0 },
1180 /* 0x6e */ { NULL, NULL, 0 },
1181 /* 0x6f */ { NULL, NULL, 0 },
1182 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1183 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1184 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1185 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1186 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1187 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1188 /* 0x76 */ { NULL, NULL, 0 },
1189 /* 0x77 */ { NULL, NULL, 0 },
1190 /* 0x78 */ { NULL, NULL, 0 },
1191 /* 0x79 */ { NULL, NULL, 0 },
1192 /* 0x7a */ { NULL, NULL, 0 },
1193 /* 0x7b */ { NULL, NULL, 0 },
1194 /* 0x7c */ { NULL, NULL, 0 },
1195 /* 0x7d */ { NULL, NULL, 0 },
1196 /* 0x7e */ { NULL, NULL, 0 },
1197 /* 0x7f */ { NULL, NULL, 0 },
1198 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1199 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1200 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1201 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1202 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1203 /* 0x85 */ { NULL, NULL, 0 },
1204 /* 0x86 */ { NULL, NULL, 0 },
1205 /* 0x87 */ { NULL, NULL, 0 },
1206 /* 0x88 */ { NULL, NULL, 0 },
1207 /* 0x89 */ { NULL, NULL, 0 },
1208 /* 0x8a */ { NULL, NULL, 0 },
1209 /* 0x8b */ { NULL, NULL, 0 },
1210 /* 0x8c */ { NULL, NULL, 0 },
1211 /* 0x8d */ { NULL, NULL, 0 },
1212 /* 0x8e */ { NULL, NULL, 0 },
1213 /* 0x8f */ { NULL, NULL, 0 },
1214 /* 0x90 */ { NULL, NULL, 0 },
1215 /* 0x91 */ { NULL, NULL, 0 },
1216 /* 0x92 */ { NULL, NULL, 0 },
1217 /* 0x93 */ { NULL, NULL, 0 },
1218 /* 0x94 */ { NULL, NULL, 0 },
1219 /* 0x95 */ { NULL, NULL, 0 },
1220 /* 0x96 */ { NULL, NULL, 0 },
1221 /* 0x97 */ { NULL, NULL, 0 },
1222 /* 0x98 */ { NULL, NULL, 0 },
1223 /* 0x99 */ { NULL, NULL, 0 },
1224 /* 0x9a */ { NULL, NULL, 0 },
1225 /* 0x9b */ { NULL, NULL, 0 },
1226 /* 0x9c */ { NULL, NULL, 0 },
1227 /* 0x9d */ { NULL, NULL, 0 },
1228 /* 0x9e */ { NULL, NULL, 0 },
1229 /* 0x9f */ { NULL, NULL, 0 },
1230 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1231 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1232 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1233 /* 0xa3 */ { NULL, NULL, 0 },
1234 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1235 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1236 /* 0xa6 */ { NULL, NULL, 0 },
1237 /* 0xa7 */ { NULL, NULL, 0 },
1238 /* 0xa8 */ { NULL, NULL, 0 },
1239 /* 0xa9 */ { NULL, NULL, 0 },
1240 /* 0xaa */ { NULL, NULL, 0 },
1241 /* 0xab */ { NULL, NULL, 0 },
1242 /* 0xac */ { NULL, NULL, 0 },
1243 /* 0xad */ { NULL, NULL, 0 },
1244 /* 0xae */ { NULL, NULL, 0 },
1245 /* 0xaf */ { NULL, NULL, 0 },
1246 /* 0xb0 */ { NULL, NULL, 0 },
1247 /* 0xb1 */ { NULL, NULL, 0 },
1248 /* 0xb2 */ { NULL, NULL, 0 },
1249 /* 0xb3 */ { NULL, NULL, 0 },
1250 /* 0xb4 */ { NULL, NULL, 0 },
1251 /* 0xb5 */ { NULL, NULL, 0 },
1252 /* 0xb6 */ { NULL, NULL, 0 },
1253 /* 0xb7 */ { NULL, NULL, 0 },
1254 /* 0xb8 */ { NULL, NULL, 0 },
1255 /* 0xb9 */ { NULL, NULL, 0 },
1256 /* 0xba */ { NULL, NULL, 0 },
1257 /* 0xbb */ { NULL, NULL, 0 },
1258 /* 0xbc */ { NULL, NULL, 0 },
1259 /* 0xbd */ { NULL, NULL, 0 },
1260 /* 0xbe */ { NULL, NULL, 0 },
1261 /* 0xbf */ { NULL, NULL, 0 },
1262 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1263 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1264 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1265 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1266 /* 0xc4 */ { NULL, NULL, 0 },
1267 /* 0xc5 */ { NULL, NULL, 0 },
1268 /* 0xc6 */ { NULL, NULL, 0 },
1269 /* 0xc7 */ { NULL, NULL, 0 },
1270 /* 0xc8 */ { NULL, NULL, 0 },
1271 /* 0xc9 */ { NULL, NULL, 0 },
1272 /* 0xca */ { NULL, NULL, 0 },
1273 /* 0xcb */ { NULL, NULL, 0 },
1274 /* 0xcc */ { NULL, NULL, 0 },
1275 /* 0xcd */ { NULL, NULL, 0 },
1276 /* 0xce */ { NULL, NULL, 0 },
1277 /* 0xcf */ { NULL, NULL, 0 },
1278 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1279 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1280 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1281 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1282 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1283 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1284 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1285 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1286 /* 0xd8 */ { NULL, NULL, 0 },
1287 /* 0xd9 */ { NULL, NULL, 0 },
1288 /* 0xda */ { NULL, NULL, 0 },
1289 /* 0xdb */ { NULL, NULL, 0 },
1290 /* 0xdc */ { NULL, NULL, 0 },
1291 /* 0xdd */ { NULL, NULL, 0 },
1292 /* 0xde */ { NULL, NULL, 0 },
1293 /* 0xdf */ { NULL, NULL, 0 },
1294 /* 0xe0 */ { NULL, NULL, 0 },
1295 /* 0xe1 */ { NULL, NULL, 0 },
1296 /* 0xe2 */ { NULL, NULL, 0 },
1297 /* 0xe3 */ { NULL, NULL, 0 },
1298 /* 0xe4 */ { NULL, NULL, 0 },
1299 /* 0xe5 */ { NULL, NULL, 0 },
1300 /* 0xe6 */ { NULL, NULL, 0 },
1301 /* 0xe7 */ { NULL, NULL, 0 },
1302 /* 0xe8 */ { NULL, NULL, 0 },
1303 /* 0xe9 */ { NULL, NULL, 0 },
1304 /* 0xea */ { NULL, NULL, 0 },
1305 /* 0xeb */ { NULL, NULL, 0 },
1306 /* 0xec */ { NULL, NULL, 0 },
1307 /* 0xed */ { NULL, NULL, 0 },
1308 /* 0xee */ { NULL, NULL, 0 },
1309 /* 0xef */ { NULL, NULL, 0 },
1310 /* 0xf0 */ { NULL, NULL, 0 },
1311 /* 0xf1 */ { NULL, NULL, 0 },
1312 /* 0xf2 */ { NULL, NULL, 0 },
1313 /* 0xf3 */ { NULL, NULL, 0 },
1314 /* 0xf4 */ { NULL, NULL, 0 },
1315 /* 0xf5 */ { NULL, NULL, 0 },
1316 /* 0xf6 */ { NULL, NULL, 0 },
1317 /* 0xf7 */ { NULL, NULL, 0 },
1318 /* 0xf8 */ { NULL, NULL, 0 },
1319 /* 0xf9 */ { NULL, NULL, 0 },
1320 /* 0xfa */ { NULL, NULL, 0 },
1321 /* 0xfb */ { NULL, NULL, 0 },
1322 /* 0xfc */ { NULL, NULL, 0 },
1323 /* 0xfd */ { NULL, NULL, 0 },
1324 /* 0xfe */ { NULL, NULL, 0 },
1325 /* 0xff */ { NULL, NULL, 0 }
1329 /*******************************************************************
1330 allocate and initialize a reply packet
1331 ********************************************************************/
1333 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1334 const char *inbuf, char **outbuf, uint8_t num_words,
1335 uint32_t num_bytes)
1338 * Protect against integer wrap
1340 if ((num_bytes > 0xffffff)
1341 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1342 char *msg;
1343 if (asprintf(&msg, "num_bytes too large: %u",
1344 (unsigned)num_bytes) == -1) {
1345 msg = CONST_DISCARD(char *, "num_bytes too large");
1347 smb_panic(msg);
1350 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1351 smb_size + num_words*2 + num_bytes);
1352 if (*outbuf == NULL) {
1353 return false;
1356 construct_reply_common(req, inbuf, *outbuf);
1357 srv_set_message(*outbuf, num_words, num_bytes, false);
1359 * Zero out the word area, the caller has to take care of the bcc area
1360 * himself
1362 if (num_words != 0) {
1363 memset(*outbuf + smb_vwv0, 0, num_words*2);
1366 return true;
1369 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1371 char *outbuf;
1372 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1373 num_bytes)) {
1374 smb_panic("could not allocate output buffer\n");
1376 req->outbuf = (uint8_t *)outbuf;
1380 /*******************************************************************
1381 Dump a packet to a file.
1382 ********************************************************************/
1384 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1386 int fd, i;
1387 char *fname = NULL;
1388 if (DEBUGLEVEL < 50) {
1389 return;
1392 if (len < 4) len = smb_len(data)+4;
1393 for (i=1;i<100;i++) {
1394 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1395 type ? "req" : "resp") == -1) {
1396 return;
1398 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1399 if (fd != -1 || errno != EEXIST) break;
1401 if (fd != -1) {
1402 ssize_t ret = write(fd, data, len);
1403 if (ret != len)
1404 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1405 close(fd);
1406 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1408 SAFE_FREE(fname);
1411 /****************************************************************************
1412 Prepare everything for calling the actual request function, and potentially
1413 call the request function via the "new" interface.
1415 Return False if the "legacy" function needs to be called, everything is
1416 prepared.
1418 Return True if we're done.
1420 I know this API sucks, but it is the one with the least code change I could
1421 find.
1422 ****************************************************************************/
1424 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1426 int flags;
1427 uint16 session_tag;
1428 connection_struct *conn = NULL;
1429 struct smbd_server_connection *sconn = req->sconn;
1431 errno = 0;
1433 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1434 * so subtract 4 from it. */
1435 if (!valid_smb_header(req->inbuf)
1436 || (size < (smb_size - 4))) {
1437 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1438 smb_len(req->inbuf)));
1439 exit_server_cleanly("Non-SMB packet");
1442 if (smb_messages[type].fn == NULL) {
1443 DEBUG(0,("Unknown message type %d!\n",type));
1444 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1445 reply_unknown_new(req, type);
1446 return NULL;
1449 flags = smb_messages[type].flags;
1451 /* In share mode security we must ignore the vuid. */
1452 session_tag = (lp_security() == SEC_SHARE)
1453 ? UID_FIELD_INVALID : req->vuid;
1454 conn = req->conn;
1456 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1457 (int)sys_getpid(), (unsigned long)conn));
1459 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1461 /* Ensure this value is replaced in the incoming packet. */
1462 SSVAL(req->inbuf,smb_uid,session_tag);
1465 * Ensure the correct username is in current_user_info. This is a
1466 * really ugly bugfix for problems with multiple session_setup_and_X's
1467 * being done and allowing %U and %G substitutions to work correctly.
1468 * There is a reason this code is done here, don't move it unless you
1469 * know what you're doing... :-).
1470 * JRA.
1473 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1474 user_struct *vuser = NULL;
1476 sconn->smb1.sessions.last_session_tag = session_tag;
1477 if(session_tag != UID_FIELD_INVALID) {
1478 vuser = get_valid_user_struct(sconn, session_tag);
1479 if (vuser) {
1480 set_current_user_info(
1481 vuser->server_info->sanitized_username,
1482 vuser->server_info->unix_name,
1483 vuser->server_info->info3->base.domain.string);
1488 /* Does this call need to be run as the connected user? */
1489 if (flags & AS_USER) {
1491 /* Does this call need a valid tree connection? */
1492 if (!conn) {
1494 * Amazingly, the error code depends on the command
1495 * (from Samba4).
1497 if (type == SMBntcreateX) {
1498 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1499 } else {
1500 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1502 return NULL;
1505 if (!change_to_user(conn,session_tag)) {
1506 DEBUG(0, ("Error: Could not change to user. Removing "
1507 "deferred open, mid=%llu.\n",
1508 (unsigned long long)req->mid));
1509 reply_force_doserror(req, ERRSRV, ERRbaduid);
1510 return conn;
1513 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1515 /* Does it need write permission? */
1516 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1517 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1518 return conn;
1521 /* IPC services are limited */
1522 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1523 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1524 return conn;
1526 } else {
1527 /* This call needs to be run as root */
1528 change_to_root_user();
1531 /* load service specific parameters */
1532 if (conn) {
1533 if (req->encrypted) {
1534 conn->encrypted_tid = true;
1535 /* encrypted required from now on. */
1536 conn->encrypt_level = Required;
1537 } else if (ENCRYPTION_REQUIRED(conn)) {
1538 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1539 exit_server_cleanly("encryption required "
1540 "on connection");
1541 return conn;
1545 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1546 (flags & (AS_USER|DO_CHDIR)
1547 ?True:False))) {
1548 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1549 return conn;
1551 conn->num_smb_operations++;
1554 /* does this protocol need to be run as guest? */
1555 if ((flags & AS_GUEST)
1556 && (!change_to_guest() ||
1557 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1558 sconn->client_id.name,
1559 sconn->client_id.addr))) {
1560 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1561 return conn;
1564 smb_messages[type].fn(req);
1565 return req->conn;
1568 /****************************************************************************
1569 Construct a reply to the incoming packet.
1570 ****************************************************************************/
1572 static void construct_reply(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, smbd_server_conn, (uint8 *)inbuf,
1584 unread_bytes, 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 *conn,
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 conn->trans_num, (int)nread, (unsigned int)unread_bytes));
1653 if (msg_type != 0) {
1655 * NetBIOS session request, keepalive, etc.
1657 reply_special(conn, (char *)inbuf, nread);
1658 goto done;
1661 if (smbd_server_conn->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(smbd_server_conn, 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 smbd_server_conn->using_smb2 = false;
1675 show_msg((char *)inbuf);
1677 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1678 conn->trans_num++;
1680 done:
1681 conn->smb1.num_requests++;
1683 /* The timeout_processing function isn't run nearly
1684 often enough to implement 'max log size' without
1685 overrunning the size of the file by many megabytes.
1686 This is especially true if we are running at debug
1687 level 10. Checking every 50 SMBs is a nice
1688 tradeoff of performance vs log file size overrun. */
1690 if ((conn->smb1.num_requests % 50) == 0 &&
1691 need_to_check_log_size()) {
1692 change_to_root_user();
1693 check_log_size();
1697 /****************************************************************************
1698 Return a string containing the function name of a SMB command.
1699 ****************************************************************************/
1701 const char *smb_fn_name(int type)
1703 const char *unknown_name = "SMBunknown";
1705 if (smb_messages[type].name == NULL)
1706 return(unknown_name);
1708 return(smb_messages[type].name);
1711 /****************************************************************************
1712 Helper functions for contruct_reply.
1713 ****************************************************************************/
1715 void add_to_common_flags2(uint32 v)
1717 common_flags2 |= v;
1720 void remove_from_common_flags2(uint32 v)
1722 common_flags2 &= ~v;
1725 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1726 char *outbuf)
1728 srv_set_message(outbuf,0,0,false);
1730 SCVAL(outbuf, smb_com, req->cmd);
1731 SIVAL(outbuf,smb_rcls,0);
1732 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1733 SSVAL(outbuf,smb_flg2,
1734 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1735 common_flags2);
1736 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1738 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1739 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1740 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1741 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1744 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1746 construct_reply_common(req, (char *)req->inbuf, outbuf);
1750 * How many bytes have we already accumulated up to the current wct field
1751 * offset?
1754 size_t req_wct_ofs(struct smb_request *req)
1756 size_t buf_size;
1758 if (req->chain_outbuf == NULL) {
1759 return smb_wct - 4;
1761 buf_size = talloc_get_size(req->chain_outbuf);
1762 if ((buf_size % 4) != 0) {
1763 buf_size += (4 - (buf_size % 4));
1765 return buf_size - 4;
1769 * Hack around reply_nterror & friends not being aware of chained requests,
1770 * generating illegal (i.e. wct==0) chain replies.
1773 static void fixup_chain_error_packet(struct smb_request *req)
1775 uint8_t *outbuf = req->outbuf;
1776 req->outbuf = NULL;
1777 reply_outbuf(req, 2, 0);
1778 memcpy(req->outbuf, outbuf, smb_wct);
1779 TALLOC_FREE(outbuf);
1780 SCVAL(req->outbuf, smb_vwv0, 0xff);
1784 * @brief Find the smb_cmd offset of the last command pushed
1785 * @param[in] buf The buffer we're building up
1786 * @retval Where can we put our next andx cmd?
1788 * While chaining requests, the "next" request we're looking at needs to put
1789 * its SMB_Command before the data the previous request already built up added
1790 * to the chain. Find the offset to the place where we have to put our cmd.
1793 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1795 uint8_t cmd;
1796 size_t ofs;
1798 cmd = CVAL(buf, smb_com);
1800 SMB_ASSERT(is_andx_req(cmd));
1802 ofs = smb_vwv0;
1804 while (CVAL(buf, ofs) != 0xff) {
1806 if (!is_andx_req(CVAL(buf, ofs))) {
1807 return false;
1811 * ofs is from start of smb header, so add the 4 length
1812 * bytes. The next cmd is right after the wct field.
1814 ofs = SVAL(buf, ofs+2) + 4 + 1;
1816 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1819 *pofs = ofs;
1820 return true;
1824 * @brief Do the smb chaining at a buffer level
1825 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1826 * @param[in] smb_command The command that we want to issue
1827 * @param[in] wct How many words?
1828 * @param[in] vwv The words, already in network order
1829 * @param[in] bytes_alignment How shall we align "bytes"?
1830 * @param[in] num_bytes How many bytes?
1831 * @param[in] bytes The data the request ships
1833 * smb_splice_chain() adds the vwv and bytes to the request already present in
1834 * *poutbuf.
1837 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1838 uint8_t wct, const uint16_t *vwv,
1839 size_t bytes_alignment,
1840 uint32_t num_bytes, const uint8_t *bytes)
1842 uint8_t *outbuf;
1843 size_t old_size, new_size;
1844 size_t ofs;
1845 size_t chain_padding = 0;
1846 size_t bytes_padding = 0;
1847 bool first_request;
1849 old_size = talloc_get_size(*poutbuf);
1852 * old_size == smb_wct means we're pushing the first request in for
1853 * libsmb/
1856 first_request = (old_size == smb_wct);
1858 if (!first_request && ((old_size % 4) != 0)) {
1860 * Align the wct field of subsequent requests to a 4-byte
1861 * boundary
1863 chain_padding = 4 - (old_size % 4);
1867 * After the old request comes the new wct field (1 byte), the vwv's
1868 * and the num_bytes field. After at we might need to align the bytes
1869 * given to us to "bytes_alignment", increasing the num_bytes value.
1872 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1874 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1875 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1878 new_size += bytes_padding + num_bytes;
1880 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1881 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1882 (unsigned)new_size));
1883 return false;
1886 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1887 if (outbuf == NULL) {
1888 DEBUG(0, ("talloc failed\n"));
1889 return false;
1891 *poutbuf = outbuf;
1893 if (first_request) {
1894 SCVAL(outbuf, smb_com, smb_command);
1895 } else {
1896 size_t andx_cmd_ofs;
1898 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1899 DEBUG(1, ("invalid command chain\n"));
1900 *poutbuf = TALLOC_REALLOC_ARRAY(
1901 NULL, *poutbuf, uint8_t, old_size);
1902 return false;
1905 if (chain_padding != 0) {
1906 memset(outbuf + old_size, 0, chain_padding);
1907 old_size += chain_padding;
1910 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1911 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1914 ofs = old_size;
1917 * Push the chained request:
1919 * wct field
1922 SCVAL(outbuf, ofs, wct);
1923 ofs += 1;
1926 * vwv array
1929 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1930 ofs += sizeof(uint16_t) * wct;
1933 * bcc (byte count)
1936 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1937 ofs += sizeof(uint16_t);
1940 * padding
1943 if (bytes_padding != 0) {
1944 memset(outbuf + ofs, 0, bytes_padding);
1945 ofs += bytes_padding;
1949 * The bytes field
1952 memcpy(outbuf + ofs, bytes, num_bytes);
1954 return true;
1957 /****************************************************************************
1958 Construct a chained reply and add it to the already made reply
1959 ****************************************************************************/
1961 void chain_reply(struct smb_request *req)
1963 size_t smblen = smb_len(req->inbuf);
1964 size_t already_used, length_needed;
1965 uint8_t chain_cmd;
1966 uint32_t chain_offset; /* uint32_t to avoid overflow */
1968 uint8_t wct;
1969 uint16_t *vwv;
1970 uint16_t buflen;
1971 uint8_t *buf;
1973 if (IVAL(req->outbuf, smb_rcls) != 0) {
1974 fixup_chain_error_packet(req);
1978 * Any of the AndX requests and replies have at least a wct of
1979 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1980 * beginning of the SMB header to the next wct field.
1982 * None of the AndX requests put anything valuable in vwv[0] and [1],
1983 * so we can overwrite it here to form the chain.
1986 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1987 if (req->chain_outbuf == NULL) {
1988 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1989 req, req->outbuf, uint8_t,
1990 smb_len(req->outbuf) + 4);
1991 if (req->chain_outbuf == NULL) {
1992 smb_panic("talloc failed");
1995 req->outbuf = NULL;
1996 goto error;
2000 * Here we assume that this is the end of the chain. For that we need
2001 * to set "next command" to 0xff and the offset to 0. If we later find
2002 * more commands in the chain, this will be overwritten again.
2005 SCVAL(req->outbuf, smb_vwv0, 0xff);
2006 SCVAL(req->outbuf, smb_vwv0+1, 0);
2007 SSVAL(req->outbuf, smb_vwv1, 0);
2009 if (req->chain_outbuf == NULL) {
2011 * In req->chain_outbuf we collect all the replies. Start the
2012 * chain by copying in the first reply.
2014 * We do the realloc because later on we depend on
2015 * talloc_get_size to determine the length of
2016 * chain_outbuf. The reply_xxx routines might have
2017 * over-allocated (reply_pipe_read_and_X used to be such an
2018 * example).
2020 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2021 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2022 if (req->chain_outbuf == NULL) {
2023 smb_panic("talloc failed");
2025 req->outbuf = NULL;
2026 } else {
2028 * Update smb headers where subsequent chained commands
2029 * may have updated them.
2031 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2032 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2034 if (!smb_splice_chain(&req->chain_outbuf,
2035 CVAL(req->outbuf, smb_com),
2036 CVAL(req->outbuf, smb_wct),
2037 (uint16_t *)(req->outbuf + smb_vwv),
2038 0, smb_buflen(req->outbuf),
2039 (uint8_t *)smb_buf(req->outbuf))) {
2040 goto error;
2042 TALLOC_FREE(req->outbuf);
2046 * We use the old request's vwv field to grab the next chained command
2047 * and offset into the chained fields.
2050 chain_cmd = CVAL(req->vwv+0, 0);
2051 chain_offset = SVAL(req->vwv+1, 0);
2053 if (chain_cmd == 0xff) {
2055 * End of chain, no more requests from the client. So ship the
2056 * replies.
2058 smb_setlen((char *)(req->chain_outbuf),
2059 talloc_get_size(req->chain_outbuf) - 4);
2061 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2062 true, req->seqnum+1,
2063 IS_CONN_ENCRYPTED(req->conn)
2064 ||req->encrypted,
2065 &req->pcd)) {
2066 exit_server_cleanly("chain_reply: srv_send_smb "
2067 "failed.");
2069 TALLOC_FREE(req->chain_outbuf);
2070 req->done = true;
2071 return;
2074 /* add a new perfcounter for this element of chain */
2075 SMB_PERFCOUNT_ADD(&req->pcd);
2076 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2077 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2080 * Check if the client tries to fool us. The request so far uses the
2081 * space to the end of the byte buffer in the request just
2082 * processed. The chain_offset can't point into that area. If that was
2083 * the case, we could end up with an endless processing of the chain,
2084 * we would always handle the same request.
2087 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2088 if (chain_offset < already_used) {
2089 goto error;
2093 * Next check: Make sure the chain offset does not point beyond the
2094 * overall smb request length.
2097 length_needed = chain_offset+1; /* wct */
2098 if (length_needed > smblen) {
2099 goto error;
2103 * Now comes the pointer magic. Goal here is to set up req->vwv and
2104 * req->buf correctly again to be able to call the subsequent
2105 * switch_message(). The chain offset (the former vwv[1]) points at
2106 * the new wct field.
2109 wct = CVAL(smb_base(req->inbuf), chain_offset);
2112 * Next consistency check: Make the new vwv array fits in the overall
2113 * smb request.
2116 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2117 if (length_needed > smblen) {
2118 goto error;
2120 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2123 * Now grab the new byte buffer....
2126 buflen = SVAL(vwv+wct, 0);
2129 * .. and check that it fits.
2132 length_needed += buflen;
2133 if (length_needed > smblen) {
2134 goto error;
2136 buf = (uint8_t *)(vwv+wct+1);
2138 req->cmd = chain_cmd;
2139 req->wct = wct;
2140 req->vwv = vwv;
2141 req->buflen = buflen;
2142 req->buf = buf;
2144 switch_message(chain_cmd, req, smblen);
2146 if (req->outbuf == NULL) {
2148 * This happens if the chained command has suspended itself or
2149 * if it has called srv_send_smb() itself.
2151 return;
2155 * We end up here if the chained command was not itself chained or
2156 * suspended, but for example a close() command. We now need to splice
2157 * the chained commands' outbuf into the already built up chain_outbuf
2158 * and ship the result.
2160 goto done;
2162 error:
2164 * We end up here if there's any error in the chain syntax. Report a
2165 * DOS error, just like Windows does.
2167 reply_force_doserror(req, ERRSRV, ERRerror);
2168 fixup_chain_error_packet(req);
2170 done:
2172 * This scary statement intends to set the
2173 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2174 * to the value req->outbuf carries
2176 SSVAL(req->chain_outbuf, smb_flg2,
2177 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2178 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2181 * Transfer the error codes from the subrequest to the main one
2183 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2184 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2186 if (!smb_splice_chain(&req->chain_outbuf,
2187 CVAL(req->outbuf, smb_com),
2188 CVAL(req->outbuf, smb_wct),
2189 (uint16_t *)(req->outbuf + smb_vwv),
2190 0, smb_buflen(req->outbuf),
2191 (uint8_t *)smb_buf(req->outbuf))) {
2192 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2194 TALLOC_FREE(req->outbuf);
2196 smb_setlen((char *)(req->chain_outbuf),
2197 talloc_get_size(req->chain_outbuf) - 4);
2199 show_msg((char *)(req->chain_outbuf));
2201 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2202 true, req->seqnum+1,
2203 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2204 &req->pcd)) {
2205 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2207 TALLOC_FREE(req->chain_outbuf);
2208 req->done = true;
2211 /****************************************************************************
2212 Check if services need reloading.
2213 ****************************************************************************/
2215 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2217 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2219 if(last_smb_conf_reload_time == 0) {
2220 last_smb_conf_reload_time = t;
2221 /* Our printing subsystem might not be ready at smbd start up.
2222 Then no printer is available till the first printers check
2223 is performed. A lower initial interval circumvents this. */
2224 if ( printcap_cache_time > 60 )
2225 last_printer_reload_time = t - printcap_cache_time + 60;
2226 else
2227 last_printer_reload_time = t;
2230 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2231 /* randomize over 60 second the printcap reload to avoid all
2232 * process hitting cupsd at the same time */
2233 int time_range = 60;
2235 last_printer_reload_time += random() % time_range;
2236 mypid = getpid();
2239 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2240 reload_services(sconn->msg_ctx, sconn->sock, True);
2241 last_smb_conf_reload_time = t;
2244 /* 'printcap cache time = 0' disable the feature */
2246 if ( printcap_cache_time != 0 )
2248 /* see if it's time to reload or if the clock has been set back */
2250 if ( (t >= last_printer_reload_time+printcap_cache_time)
2251 || (t-last_printer_reload_time < 0) )
2253 DEBUG( 3,( "Printcap cache time expired.\n"));
2254 reload_printers(sconn->msg_ctx);
2255 last_printer_reload_time = t;
2260 static bool fd_is_readable(int fd)
2262 fd_set fds;
2263 struct timeval timeout = {0, };
2264 int ret;
2266 FD_ZERO(&fds);
2267 FD_SET(fd, &fds);
2269 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2270 if (ret == -1) {
2271 return false;
2273 return FD_ISSET(fd, &fds);
2276 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2278 /* TODO: make write nonblocking */
2281 static void smbd_server_connection_read_handler(
2282 struct smbd_server_connection *conn, int fd)
2284 uint8_t *inbuf = NULL;
2285 size_t inbuf_len = 0;
2286 size_t unread_bytes = 0;
2287 bool encrypted = false;
2288 TALLOC_CTX *mem_ctx = talloc_tos();
2289 NTSTATUS status;
2290 uint32_t seqnum;
2292 bool from_client = (conn->sock == fd);
2294 if (from_client) {
2295 smbd_lock_socket(conn);
2297 if (!fd_is_readable(fd)) {
2298 DEBUG(10,("the echo listener was faster\n"));
2299 smbd_unlock_socket(conn);
2300 return;
2303 /* TODO: make this completely nonblocking */
2304 status = receive_smb_talloc(mem_ctx, fd,
2305 (char **)(void *)&inbuf,
2306 0, /* timeout */
2307 &unread_bytes,
2308 &encrypted,
2309 &inbuf_len, &seqnum,
2310 false /* trusted channel */);
2311 smbd_unlock_socket(conn);
2312 } else {
2313 /* TODO: make this completely nonblocking */
2314 status = receive_smb_talloc(mem_ctx, fd,
2315 (char **)(void *)&inbuf,
2316 0, /* timeout */
2317 &unread_bytes,
2318 &encrypted,
2319 &inbuf_len, &seqnum,
2320 true /* trusted channel */);
2323 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2324 goto process;
2326 if (NT_STATUS_IS_ERR(status)) {
2327 exit_server_cleanly("failed to receive smb request");
2329 if (!NT_STATUS_IS_OK(status)) {
2330 return;
2333 process:
2334 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2335 seqnum, encrypted, NULL);
2338 static void smbd_server_connection_handler(struct event_context *ev,
2339 struct fd_event *fde,
2340 uint16_t flags,
2341 void *private_data)
2343 struct smbd_server_connection *conn = talloc_get_type(private_data,
2344 struct smbd_server_connection);
2346 if (flags & EVENT_FD_WRITE) {
2347 smbd_server_connection_write_handler(conn);
2348 return;
2350 if (flags & EVENT_FD_READ) {
2351 smbd_server_connection_read_handler(conn, conn->sock);
2352 return;
2356 static void smbd_server_echo_handler(struct event_context *ev,
2357 struct fd_event *fde,
2358 uint16_t flags,
2359 void *private_data)
2361 struct smbd_server_connection *conn = talloc_get_type(private_data,
2362 struct smbd_server_connection);
2364 if (flags & EVENT_FD_WRITE) {
2365 smbd_server_connection_write_handler(conn);
2366 return;
2368 if (flags & EVENT_FD_READ) {
2369 smbd_server_connection_read_handler(
2370 conn, conn->smb1.echo_handler.trusted_fd);
2371 return;
2375 /****************************************************************************
2376 received when we should release a specific IP
2377 ****************************************************************************/
2378 static void release_ip(const char *ip, void *priv)
2380 const char *addr = (const char *)priv;
2381 const char *p = addr;
2383 if (strncmp("::ffff:", addr, 7) == 0) {
2384 p = addr + 7;
2387 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2388 /* we can't afford to do a clean exit - that involves
2389 database writes, which would potentially mean we
2390 are still running after the failover has finished -
2391 we have to get rid of this process ID straight
2392 away */
2393 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2394 ip));
2395 /* note we must exit with non-zero status so the unclean handler gets
2396 called in the parent, so that the brl database is tickled */
2397 _exit(1);
2401 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2402 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2404 struct smbd_server_connection *sconn = talloc_get_type_abort(
2405 private_data, struct smbd_server_connection);
2407 release_ip((char *)data->data, sconn->client_id.addr);
2410 #ifdef CLUSTER_SUPPORT
2411 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2412 struct sockaddr_storage *client)
2414 socklen_t length;
2415 length = sizeof(*server);
2416 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2417 return -1;
2419 length = sizeof(*client);
2420 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2421 return -1;
2423 return 0;
2425 #endif
2428 * Send keepalive packets to our client
2430 static bool keepalive_fn(const struct timeval *now, void *private_data)
2432 struct smbd_server_connection *sconn = smbd_server_conn;
2433 bool ret;
2435 if (sconn->using_smb2) {
2436 /* Don't do keepalives on an SMB2 connection. */
2437 return false;
2440 smbd_lock_socket(smbd_server_conn);
2441 ret = send_keepalive(sconn->sock);
2442 smbd_unlock_socket(smbd_server_conn);
2444 if (!ret) {
2445 char addr[INET6_ADDRSTRLEN];
2447 * Try and give an error message saying what
2448 * client failed.
2450 DEBUG(0, ("send_keepalive failed for client %s. "
2451 "Error %s - exiting\n",
2452 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2453 strerror(errno)));
2454 return False;
2456 return True;
2460 * Do the recurring check if we're idle
2462 static bool deadtime_fn(const struct timeval *now, void *private_data)
2464 struct smbd_server_connection *sconn =
2465 (struct smbd_server_connection *)private_data;
2467 if (sconn->using_smb2) {
2468 /* TODO: implement real idle check */
2469 if (sconn->smb2.sessions.list) {
2470 return true;
2472 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2473 messaging_send(sconn->msg_ctx,
2474 messaging_server_id(sconn->msg_ctx),
2475 MSG_SHUTDOWN, &data_blob_null);
2476 return false;
2479 if ((conn_num_open(sconn) == 0)
2480 || (conn_idle_all(sconn, now->tv_sec))) {
2481 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2482 messaging_send(sconn->msg_ctx,
2483 messaging_server_id(sconn->msg_ctx),
2484 MSG_SHUTDOWN, &data_blob_null);
2485 return False;
2488 return True;
2492 * Do the recurring log file and smb.conf reload checks.
2495 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2497 struct smbd_server_connection *sconn = talloc_get_type_abort(
2498 private_data, struct smbd_server_connection);
2499 change_to_root_user();
2501 /* update printer queue caches if necessary */
2502 update_monitored_printq_cache(sconn->msg_ctx);
2504 /* check if we need to reload services */
2505 check_reload(sconn, time(NULL));
2507 /* Change machine password if neccessary. */
2508 attempt_machine_password_change();
2511 * Force a log file check.
2513 force_check_log_size();
2514 check_log_size();
2515 return true;
2518 static int create_unlink_tmp(const char *dir)
2520 char *fname;
2521 int fd;
2523 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2524 if (fname == NULL) {
2525 errno = ENOMEM;
2526 return -1;
2528 fd = mkstemp(fname);
2529 if (fd == -1) {
2530 TALLOC_FREE(fname);
2531 return -1;
2533 if (unlink(fname) == -1) {
2534 int sys_errno = errno;
2535 close(fd);
2536 TALLOC_FREE(fname);
2537 errno = sys_errno;
2538 return -1;
2540 TALLOC_FREE(fname);
2541 return fd;
2544 struct smbd_echo_state {
2545 struct tevent_context *ev;
2546 struct iovec *pending;
2547 struct smbd_server_connection *sconn;
2548 int parent_pipe;
2550 struct tevent_fd *parent_fde;
2552 struct tevent_fd *read_fde;
2553 struct tevent_req *write_req;
2556 static void smbd_echo_writer_done(struct tevent_req *req);
2558 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2560 int num_pending;
2562 if (state->write_req != NULL) {
2563 return;
2566 num_pending = talloc_array_length(state->pending);
2567 if (num_pending == 0) {
2568 return;
2571 state->write_req = writev_send(state, state->ev, NULL,
2572 state->parent_pipe, false,
2573 state->pending, num_pending);
2574 if (state->write_req == NULL) {
2575 DEBUG(1, ("writev_send failed\n"));
2576 exit(1);
2579 talloc_steal(state->write_req, state->pending);
2580 state->pending = NULL;
2582 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2583 state);
2586 static void smbd_echo_writer_done(struct tevent_req *req)
2588 struct smbd_echo_state *state = tevent_req_callback_data(
2589 req, struct smbd_echo_state);
2590 ssize_t written;
2591 int err;
2593 written = writev_recv(req, &err);
2594 TALLOC_FREE(req);
2595 state->write_req = NULL;
2596 if (written == -1) {
2597 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2598 exit(1);
2600 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2601 smbd_echo_activate_writer(state);
2604 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2605 uint32_t seqnum)
2607 struct smb_request req;
2608 uint16_t num_replies;
2609 size_t out_len;
2610 char *outbuf;
2611 bool ok;
2613 if (inbuf_len < smb_size) {
2614 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2615 return false;
2617 if (!valid_smb_header(inbuf)) {
2618 DEBUG(10, ("Got invalid SMB header\n"));
2619 return false;
2622 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2623 seqnum)) {
2624 return false;
2626 req.inbuf = inbuf;
2628 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2629 smb_messages[req.cmd].name
2630 ? smb_messages[req.cmd].name : "unknown"));
2632 if (req.cmd != SMBecho) {
2633 return false;
2635 if (req.wct < 1) {
2636 return false;
2639 num_replies = SVAL(req.vwv+0, 0);
2640 if (num_replies != 1) {
2641 /* Not a Windows "Hey, you're still there?" request */
2642 return false;
2645 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2646 1, req.buflen)) {
2647 DEBUG(10, ("create_outbuf failed\n"));
2648 return false;
2650 req.outbuf = (uint8_t *)outbuf;
2652 SSVAL(req.outbuf, smb_vwv0, num_replies);
2654 if (req.buflen > 0) {
2655 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2658 out_len = smb_len(req.outbuf) + 4;
2660 ok = srv_send_smb(req.sconn,
2661 (char *)outbuf,
2662 true, seqnum+1,
2663 false, &req.pcd);
2664 TALLOC_FREE(outbuf);
2665 if (!ok) {
2666 exit(1);
2669 return true;
2672 static void smbd_echo_exit(struct tevent_context *ev,
2673 struct tevent_fd *fde, uint16_t flags,
2674 void *private_data)
2676 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2677 exit(0);
2680 static void smbd_echo_reader(struct tevent_context *ev,
2681 struct tevent_fd *fde, uint16_t flags,
2682 void *private_data)
2684 struct smbd_echo_state *state = talloc_get_type_abort(
2685 private_data, struct smbd_echo_state);
2686 struct smbd_server_connection *sconn = state->sconn;
2687 size_t unread, num_pending;
2688 NTSTATUS status;
2689 struct iovec *tmp;
2690 size_t iov_len;
2691 uint32_t seqnum = 0;
2692 bool reply;
2693 bool ok;
2694 bool encrypted = false;
2696 smb_msleep(1000);
2698 ok = smbd_lock_socket_internal(sconn);
2699 if (!ok) {
2700 DEBUG(0, ("%s: failed to lock socket\n",
2701 __location__));
2702 exit(1);
2705 if (!fd_is_readable(sconn->sock)) {
2706 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2707 (int)sys_getpid()));
2708 ok = smbd_unlock_socket_internal(sconn);
2709 if (!ok) {
2710 DEBUG(1, ("%s: failed to unlock socket in\n",
2711 __location__));
2712 exit(1);
2714 return;
2717 num_pending = talloc_array_length(state->pending);
2718 tmp = talloc_realloc(state, state->pending, struct iovec,
2719 num_pending+1);
2720 if (tmp == NULL) {
2721 DEBUG(1, ("talloc_realloc failed\n"));
2722 exit(1);
2724 state->pending = tmp;
2726 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2728 status = receive_smb_talloc(state->pending, sconn->sock,
2729 (char **)(void *)&state->pending[num_pending].iov_base,
2730 0 /* timeout */,
2731 &unread,
2732 &encrypted,
2733 &iov_len,
2734 &seqnum,
2735 false /* trusted_channel*/);
2736 if (!NT_STATUS_IS_OK(status)) {
2737 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2738 (int)sys_getpid(), nt_errstr(status)));
2739 exit(1);
2741 state->pending[num_pending].iov_len = iov_len;
2743 ok = smbd_unlock_socket_internal(sconn);
2744 if (!ok) {
2745 DEBUG(1, ("%s: failed to unlock socket in\n",
2746 __location__));
2747 exit(1);
2751 * place the seqnum in the packet so that the main process can reply
2752 * with signing
2754 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2755 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2757 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2758 state->pending[num_pending].iov_len,
2759 seqnum);
2760 if (reply) {
2761 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2762 /* no check, shrinking by some bytes does not fail */
2763 state->pending = talloc_realloc(state, state->pending,
2764 struct iovec,
2765 num_pending);
2766 } else {
2767 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2768 smbd_echo_activate_writer(state);
2772 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2773 int parent_pipe)
2775 struct smbd_echo_state *state;
2777 state = talloc_zero(sconn, struct smbd_echo_state);
2778 if (state == NULL) {
2779 DEBUG(1, ("talloc failed\n"));
2780 return;
2782 state->sconn = sconn;
2783 state->parent_pipe = parent_pipe;
2784 state->ev = s3_tevent_context_init(state);
2785 if (state->ev == NULL) {
2786 DEBUG(1, ("tevent_context_init failed\n"));
2787 TALLOC_FREE(state);
2788 return;
2790 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2791 TEVENT_FD_READ, smbd_echo_exit,
2792 state);
2793 if (state->parent_fde == NULL) {
2794 DEBUG(1, ("tevent_add_fd failed\n"));
2795 TALLOC_FREE(state);
2796 return;
2798 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2799 TEVENT_FD_READ, smbd_echo_reader,
2800 state);
2801 if (state->read_fde == NULL) {
2802 DEBUG(1, ("tevent_add_fd failed\n"));
2803 TALLOC_FREE(state);
2804 return;
2807 while (true) {
2808 if (tevent_loop_once(state->ev) == -1) {
2809 DEBUG(1, ("tevent_loop_once failed: %s\n",
2810 strerror(errno)));
2811 break;
2814 TALLOC_FREE(state);
2818 * Handle SMBecho requests in a forked child process
2820 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2822 int listener_pipe[2];
2823 int res;
2824 pid_t child;
2826 res = pipe(listener_pipe);
2827 if (res == -1) {
2828 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2829 return false;
2831 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2832 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2833 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2834 goto fail;
2837 child = sys_fork();
2838 if (child == 0) {
2839 NTSTATUS status;
2841 close(listener_pipe[0]);
2843 status = reinit_after_fork(sconn->msg_ctx,
2844 smbd_event_context(),
2845 procid_self(), false);
2846 if (!NT_STATUS_IS_OK(status)) {
2847 DEBUG(1, ("reinit_after_fork failed: %s\n",
2848 nt_errstr(status)));
2849 exit(1);
2851 smbd_echo_loop(sconn, listener_pipe[1]);
2852 exit(0);
2854 close(listener_pipe[1]);
2855 listener_pipe[1] = -1;
2856 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2858 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2861 * Without smb signing this is the same as the normal smbd
2862 * listener. This needs to change once signing comes in.
2864 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2865 sconn,
2866 sconn->smb1.echo_handler.trusted_fd,
2867 EVENT_FD_READ,
2868 smbd_server_echo_handler,
2869 sconn);
2870 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2871 DEBUG(1, ("event_add_fd failed\n"));
2872 goto fail;
2875 return true;
2877 fail:
2878 if (listener_pipe[0] != -1) {
2879 close(listener_pipe[0]);
2881 if (listener_pipe[1] != -1) {
2882 close(listener_pipe[1]);
2884 sconn->smb1.echo_handler.trusted_fd = -1;
2885 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2886 close(sconn->smb1.echo_handler.socket_lock_fd);
2888 sconn->smb1.echo_handler.trusted_fd = -1;
2889 sconn->smb1.echo_handler.socket_lock_fd = -1;
2890 return false;
2893 #if CLUSTER_SUPPORT
2895 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2896 struct sockaddr_storage *srv,
2897 struct sockaddr_storage *clnt)
2899 struct ctdbd_connection *cconn;
2900 char tmp_addr[INET6_ADDRSTRLEN];
2901 char *addr;
2903 cconn = messaging_ctdbd_connection();
2904 if (cconn == NULL) {
2905 return NT_STATUS_NO_MEMORY;
2908 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2909 addr = talloc_strdup(cconn, tmp_addr);
2910 if (addr == NULL) {
2911 return NT_STATUS_NO_MEMORY;
2913 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2916 #endif
2918 /****************************************************************************
2919 Process commands from the client
2920 ****************************************************************************/
2922 void smbd_process(struct smbd_server_connection *sconn)
2924 TALLOC_CTX *frame = talloc_stackframe();
2925 struct sockaddr_storage ss;
2926 struct sockaddr *sa = NULL;
2927 socklen_t sa_socklen;
2928 struct tsocket_address *local_address = NULL;
2929 struct tsocket_address *remote_address = NULL;
2930 const char *remaddr = NULL;
2931 int ret;
2933 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2934 lp_security() != SEC_SHARE &&
2935 !lp_async_smb_echo_handler()) {
2937 * We're not making the desion here,
2938 * we're just allowing the client
2939 * to decide between SMB1 and SMB2
2940 * with the first negprot
2941 * packet.
2943 sconn->using_smb2 = true;
2946 /* Ensure child is set to blocking mode */
2947 set_blocking(sconn->sock,True);
2949 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2950 set_socket_options(sconn->sock, lp_socket_options());
2952 sa = (struct sockaddr *)(void *)&ss;
2953 sa_socklen = sizeof(ss);
2954 ret = getpeername(sconn->sock, sa, &sa_socklen);
2955 if (ret != 0) {
2956 int level = (errno == ENOTCONN)?2:0;
2957 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2958 exit_server_cleanly("getpeername() failed.\n");
2960 ret = tsocket_address_bsd_from_sockaddr(sconn,
2961 sa, sa_socklen,
2962 &remote_address);
2963 if (ret != 0) {
2964 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2965 __location__, strerror(errno)));
2966 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2969 sa = (struct sockaddr *)(void *)&ss;
2970 sa_socklen = sizeof(ss);
2971 ret = getsockname(sconn->sock, sa, &sa_socklen);
2972 if (ret != 0) {
2973 int level = (errno == ENOTCONN)?2:0;
2974 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2975 exit_server_cleanly("getsockname() failed.\n");
2977 ret = tsocket_address_bsd_from_sockaddr(sconn,
2978 sa, sa_socklen,
2979 &local_address);
2980 if (ret != 0) {
2981 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2982 __location__, strerror(errno)));
2983 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2986 sconn->local_address = local_address;
2987 sconn->remote_address = remote_address;
2989 if (tsocket_address_is_inet(remote_address, "ip")) {
2990 remaddr = tsocket_address_inet_addr_string(
2991 sconn->remote_address,
2992 talloc_tos());
2993 if (remaddr == NULL) {
2996 } else {
2997 remaddr = "0.0.0.0";
3000 /* this is needed so that we get decent entries
3001 in smbstatus for port 445 connects */
3002 set_remote_machine_name(remaddr, false);
3003 reload_services(sconn->msg_ctx, sconn->sock, true);
3006 * Before the first packet, check the global hosts allow/ hosts deny
3007 * parameters before doing any parsing of packets passed to us by the
3008 * client. This prevents attacks on our parsing code from hosts not in
3009 * the hosts allow list.
3012 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3013 sconn->client_id.name,
3014 sconn->client_id.addr)) {
3016 * send a negative session response "not listening on calling
3017 * name"
3019 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3020 DEBUG( 1, ("Connection denied from %s to %s\n",
3021 tsocket_address_string(remote_address, talloc_tos()),
3022 tsocket_address_string(local_address, talloc_tos())));
3023 (void)srv_send_smb(sconn,(char *)buf, false,
3024 0, false, NULL);
3025 exit_server_cleanly("connection denied");
3028 DEBUG(10, ("Connection allowed from %s to %s\n",
3029 tsocket_address_string(remote_address, talloc_tos()),
3030 tsocket_address_string(local_address, talloc_tos())));
3032 init_modules();
3034 smb_perfcount_init();
3036 if (!init_account_policy()) {
3037 exit_server("Could not open account policy tdb.\n");
3040 if (*lp_rootdir()) {
3041 if (chroot(lp_rootdir()) != 0) {
3042 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3043 exit_server("Failed to chroot()");
3045 if (chdir("/") == -1) {
3046 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3047 exit_server("Failed to chroot()");
3049 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3052 if (!srv_init_signing(sconn)) {
3053 exit_server("Failed to init smb_signing");
3056 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3057 exit_server("Failed to fork echo handler");
3060 /* Setup oplocks */
3061 if (!init_oplocks(sconn->msg_ctx))
3062 exit_server("Failed to init oplocks");
3064 /* register our message handlers */
3065 messaging_register(sconn->msg_ctx, NULL,
3066 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3067 messaging_register(sconn->msg_ctx, sconn,
3068 MSG_SMB_RELEASE_IP, msg_release_ip);
3069 messaging_register(sconn->msg_ctx, NULL,
3070 MSG_SMB_CLOSE_FILE, msg_close_file);
3073 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3074 * MSGs to all child processes
3076 messaging_deregister(sconn->msg_ctx,
3077 MSG_DEBUG, NULL);
3078 messaging_register(sconn->msg_ctx, NULL,
3079 MSG_DEBUG, debug_message);
3081 if ((lp_keepalive() != 0)
3082 && !(event_add_idle(smbd_event_context(), NULL,
3083 timeval_set(lp_keepalive(), 0),
3084 "keepalive", keepalive_fn,
3085 NULL))) {
3086 DEBUG(0, ("Could not add keepalive event\n"));
3087 exit(1);
3090 if (!(event_add_idle(smbd_event_context(), NULL,
3091 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3092 "deadtime", deadtime_fn, sconn))) {
3093 DEBUG(0, ("Could not add deadtime event\n"));
3094 exit(1);
3097 if (!(event_add_idle(smbd_event_context(), NULL,
3098 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3099 "housekeeping", housekeeping_fn, sconn))) {
3100 DEBUG(0, ("Could not add housekeeping event\n"));
3101 exit(1);
3104 #ifdef CLUSTER_SUPPORT
3106 if (lp_clustering()) {
3108 * We need to tell ctdb about our client's TCP
3109 * connection, so that for failover ctdbd can send
3110 * tickle acks, triggering a reconnection by the
3111 * client.
3114 struct sockaddr_storage srv, clnt;
3116 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3117 NTSTATUS status;
3118 status = smbd_register_ips(sconn, &srv, &clnt);
3119 if (!NT_STATUS_IS_OK(status)) {
3120 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3121 nt_errstr(status)));
3123 } else
3125 DEBUG(0,("Unable to get tcp info for "
3126 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3127 strerror(errno)));
3131 #endif
3133 sconn->nbt.got_session = false;
3135 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3137 sconn->smb1.sessions.done_sesssetup = false;
3138 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3139 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3140 /* users from session setup */
3141 sconn->smb1.sessions.session_userlist = NULL;
3142 /* workgroup from session setup. */
3143 sconn->smb1.sessions.session_workgroup = NULL;
3144 /* this holds info on user ids that are already validated for this VC */
3145 sconn->smb1.sessions.validated_users = NULL;
3146 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3147 sconn->smb1.sessions.num_validated_vuids = 0;
3149 conn_init(sconn);
3150 if (!init_dptrs(sconn)) {
3151 exit_server("init_dptrs() failed");
3154 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3155 sconn,
3156 sconn->sock,
3157 EVENT_FD_READ,
3158 smbd_server_connection_handler,
3159 sconn);
3160 if (!sconn->smb1.fde) {
3161 exit_server("failed to create smbd_server_connection fde");
3164 TALLOC_FREE(frame);
3166 while (True) {
3167 NTSTATUS status;
3169 frame = talloc_stackframe_pool(8192);
3171 errno = 0;
3173 status = smbd_server_connection_loop_once(sconn);
3174 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3175 !NT_STATUS_IS_OK(status)) {
3176 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3177 " exiting\n", nt_errstr(status)));
3178 break;
3181 TALLOC_FREE(frame);
3184 exit_server_cleanly(NULL);
3187 bool req_is_in_chain(struct smb_request *req)
3189 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3191 * We're right now handling a subsequent request, so we must
3192 * be in a chain
3194 return true;
3197 if (!is_andx_req(req->cmd)) {
3198 return false;
3201 if (req->wct < 2) {
3203 * Okay, an illegal request, but definitely not chained :-)
3205 return false;
3208 return (CVAL(req->vwv+0, 0) != 0xFF);