s3: Remove smbd_server_fd() from smbd_echo_loop
[Samba/ita.git] / source3 / smbd / process.c
blob769838fa010b6052bf77613a00292f3a7ee96a3b
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"
26 extern bool global_machine_password_needs_changing;
28 static void construct_reply_common(struct smb_request *req, const char *inbuf,
29 char *outbuf);
30 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
32 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
34 bool ok;
36 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
37 return true;
40 sconn->smb1.echo_handler.ref_count++;
42 if (sconn->smb1.echo_handler.ref_count > 1) {
43 return true;
46 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
48 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
49 SMB_F_SETLKW, 0, 0, F_WRLCK);
50 if (!ok) {
51 return false;
54 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
56 return true;
59 void smbd_lock_socket(struct smbd_server_connection *sconn)
61 if (!smbd_lock_socket_internal(sconn)) {
62 exit_server_cleanly("failed to lock socket");
66 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
68 bool ok;
70 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
71 return true;
74 sconn->smb1.echo_handler.ref_count--;
76 if (sconn->smb1.echo_handler.ref_count > 0) {
77 return true;
80 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
81 SMB_F_SETLKW, 0, 0, F_UNLCK);
82 if (!ok) {
83 return false;
86 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
88 return true;
91 void smbd_unlock_socket(struct smbd_server_connection *sconn)
93 if (!smbd_unlock_socket_internal(sconn)) {
94 exit_server_cleanly("failed to unlock socket");
98 /* Accessor function for smb_read_error for smbd functions. */
100 /****************************************************************************
101 Send an smb to a fd.
102 ****************************************************************************/
104 bool srv_send_smb(int fd, char *buffer,
105 bool do_signing, uint32_t seqnum,
106 bool do_encrypt,
107 struct smb_perfcount_data *pcd)
109 size_t len = 0;
110 size_t nwritten=0;
111 ssize_t ret;
112 char *buf_out = buffer;
114 smbd_lock_socket(smbd_server_conn);
116 if (do_signing) {
117 /* Sign the outgoing packet if required. */
118 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
121 if (do_encrypt) {
122 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
123 if (!NT_STATUS_IS_OK(status)) {
124 DEBUG(0, ("send_smb: SMB encryption failed "
125 "on outgoing packet! Error %s\n",
126 nt_errstr(status) ));
127 goto out;
131 len = smb_len(buf_out) + 4;
133 ret = write_data(fd,buf_out+nwritten,len - nwritten);
134 if (ret <= 0) {
135 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
136 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
137 srv_free_enc_buffer(buf_out);
138 goto out;
141 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
142 srv_free_enc_buffer(buf_out);
143 out:
144 SMB_PERFCOUNT_END(pcd);
146 smbd_unlock_socket(smbd_server_conn);
147 return true;
150 /*******************************************************************
151 Setup the word count and byte count for a smb message.
152 ********************************************************************/
154 int srv_set_message(char *buf,
155 int num_words,
156 int num_bytes,
157 bool zero)
159 if (zero && (num_words || num_bytes)) {
160 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
162 SCVAL(buf,smb_wct,num_words);
163 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
164 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
165 return (smb_size + num_words*2 + num_bytes);
168 static bool valid_smb_header(const uint8_t *inbuf)
170 if (is_encrypted_packet(inbuf)) {
171 return true;
174 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
175 * but it just looks weird to call strncmp for this one.
177 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
180 /* Socket functions for smbd packet processing. */
182 static bool valid_packet_size(size_t len)
185 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
186 * of header. Don't print the error if this fits.... JRA.
189 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
190 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
191 (unsigned long)len));
192 return false;
194 return true;
197 static NTSTATUS read_packet_remainder(int fd, char *buffer,
198 unsigned int timeout, ssize_t len)
200 if (len <= 0) {
201 return NT_STATUS_OK;
204 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
207 /****************************************************************************
208 Attempt a zerocopy writeX read. We know here that len > smb_size-4
209 ****************************************************************************/
212 * Unfortunately, earlier versions of smbclient/libsmbclient
213 * don't send this "standard" writeX header. I've fixed this
214 * for 3.2 but we'll use the old method with earlier versions.
215 * Windows and CIFSFS at least use this standard size. Not
216 * sure about MacOSX.
219 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
220 (2*14) + /* word count (including bcc) */ \
221 1 /* pad byte */)
223 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
224 const char lenbuf[4],
225 int fd, char **buffer,
226 unsigned int timeout,
227 size_t *p_unread,
228 size_t *len_ret)
230 /* Size of a WRITEX call (+4 byte len). */
231 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
232 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
233 ssize_t toread;
234 NTSTATUS status;
236 memcpy(writeX_header, lenbuf, 4);
238 status = read_fd_with_timeout(
239 fd, writeX_header + 4,
240 STANDARD_WRITE_AND_X_HEADER_SIZE,
241 STANDARD_WRITE_AND_X_HEADER_SIZE,
242 timeout, NULL);
244 if (!NT_STATUS_IS_OK(status)) {
245 return status;
249 * Ok - now try and see if this is a possible
250 * valid writeX call.
253 if (is_valid_writeX_buffer(smbd_server_conn,
254 (uint8_t *)writeX_header)) {
256 * If the data offset is beyond what
257 * we've read, drain the extra bytes.
259 uint16_t doff = SVAL(writeX_header,smb_vwv11);
260 ssize_t newlen;
262 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
263 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
264 if (drain_socket(fd, drain) != drain) {
265 smb_panic("receive_smb_raw_talloc_partial_read:"
266 " failed to drain pending bytes");
268 } else {
269 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
272 /* Spoof down the length and null out the bcc. */
273 set_message_bcc(writeX_header, 0);
274 newlen = smb_len(writeX_header);
276 /* Copy the header we've written. */
278 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
279 writeX_header,
280 sizeof(writeX_header));
282 if (*buffer == NULL) {
283 DEBUG(0, ("Could not allocate inbuf of length %d\n",
284 (int)sizeof(writeX_header)));
285 return NT_STATUS_NO_MEMORY;
288 /* Work out the remaining bytes. */
289 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
290 *len_ret = newlen + 4;
291 return NT_STATUS_OK;
294 if (!valid_packet_size(len)) {
295 return NT_STATUS_INVALID_PARAMETER;
299 * Not a valid writeX call. Just do the standard
300 * talloc and return.
303 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
305 if (*buffer == NULL) {
306 DEBUG(0, ("Could not allocate inbuf of length %d\n",
307 (int)len+4));
308 return NT_STATUS_NO_MEMORY;
311 /* Copy in what we already read. */
312 memcpy(*buffer,
313 writeX_header,
314 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
315 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
317 if(toread > 0) {
318 status = read_packet_remainder(
319 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
320 timeout, toread);
322 if (!NT_STATUS_IS_OK(status)) {
323 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
324 nt_errstr(status)));
325 return status;
329 *len_ret = len + 4;
330 return NT_STATUS_OK;
333 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
334 char **buffer, unsigned int timeout,
335 size_t *p_unread, size_t *plen)
337 char lenbuf[4];
338 size_t len;
339 int min_recv_size = lp_min_receive_file_size();
340 NTSTATUS status;
342 *p_unread = 0;
344 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
345 if (!NT_STATUS_IS_OK(status)) {
346 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
347 return status;
350 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
351 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
352 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
353 !srv_is_signing_active(smbd_server_conn) &&
354 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
356 return receive_smb_raw_talloc_partial_read(
357 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
360 if (!valid_packet_size(len)) {
361 return NT_STATUS_INVALID_PARAMETER;
365 * The +4 here can't wrap, we've checked the length above already.
368 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
370 if (*buffer == NULL) {
371 DEBUG(0, ("Could not allocate inbuf of length %d\n",
372 (int)len+4));
373 return NT_STATUS_NO_MEMORY;
376 memcpy(*buffer, lenbuf, sizeof(lenbuf));
378 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
379 if (!NT_STATUS_IS_OK(status)) {
380 return status;
383 *plen = len + 4;
384 return NT_STATUS_OK;
387 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
388 char **buffer, unsigned int timeout,
389 size_t *p_unread, bool *p_encrypted,
390 size_t *p_len,
391 uint32_t *seqnum,
392 bool trusted_channel)
394 size_t len = 0;
395 NTSTATUS status;
397 *p_encrypted = false;
399 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
400 p_unread, &len);
401 if (!NT_STATUS_IS_OK(status)) {
402 return status;
405 if (is_encrypted_packet((uint8_t *)*buffer)) {
406 status = srv_decrypt_buffer(*buffer);
407 if (!NT_STATUS_IS_OK(status)) {
408 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
409 "incoming packet! Error %s\n",
410 nt_errstr(status) ));
411 return status;
413 *p_encrypted = true;
416 /* Check the incoming SMB signature. */
417 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
418 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
419 "incoming packet!\n"));
420 return NT_STATUS_INVALID_NETWORK_RESPONSE;
423 *p_len = len;
424 return NT_STATUS_OK;
428 * Initialize a struct smb_request from an inbuf
431 static bool init_smb_request(struct smb_request *req,
432 struct smbd_server_connection *sconn,
433 const uint8 *inbuf,
434 size_t unread_bytes, bool encrypted,
435 uint32_t seqnum)
437 size_t req_size = smb_len(inbuf) + 4;
438 /* Ensure we have at least smb_size bytes. */
439 if (req_size < smb_size) {
440 DEBUG(0,("init_smb_request: invalid request size %u\n",
441 (unsigned int)req_size ));
442 return false;
444 req->cmd = CVAL(inbuf, smb_com);
445 req->flags2 = SVAL(inbuf, smb_flg2);
446 req->smbpid = SVAL(inbuf, smb_pid);
447 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
448 req->seqnum = seqnum;
449 req->vuid = SVAL(inbuf, smb_uid);
450 req->tid = SVAL(inbuf, smb_tid);
451 req->wct = CVAL(inbuf, smb_wct);
452 req->vwv = (uint16_t *)(inbuf+smb_vwv);
453 req->buflen = smb_buflen(inbuf);
454 req->buf = (const uint8_t *)smb_buf(inbuf);
455 req->unread_bytes = unread_bytes;
456 req->encrypted = encrypted;
457 req->sconn = sconn;
458 req->conn = conn_find(sconn,req->tid);
459 req->chain_fsp = NULL;
460 req->chain_outbuf = NULL;
461 req->done = false;
462 req->smb2req = NULL;
463 smb_init_perfcount_data(&req->pcd);
465 /* Ensure we have at least wct words and 2 bytes of bcc. */
466 if (smb_size + req->wct*2 > req_size) {
467 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
468 (unsigned int)req->wct,
469 (unsigned int)req_size));
470 return false;
472 /* Ensure bcc is correct. */
473 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
474 DEBUG(0,("init_smb_request: invalid bcc number %u "
475 "(wct = %u, size %u)\n",
476 (unsigned int)req->buflen,
477 (unsigned int)req->wct,
478 (unsigned int)req_size));
479 return false;
482 req->outbuf = NULL;
483 return true;
486 static void process_smb(struct smbd_server_connection *conn,
487 uint8_t *inbuf, size_t nread, size_t unread_bytes,
488 uint32_t seqnum, bool encrypted,
489 struct smb_perfcount_data *deferred_pcd);
491 static void smbd_deferred_open_timer(struct event_context *ev,
492 struct timed_event *te,
493 struct timeval _tval,
494 void *private_data)
496 struct pending_message_list *msg = talloc_get_type(private_data,
497 struct pending_message_list);
498 TALLOC_CTX *mem_ctx = talloc_tos();
499 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
500 uint8_t *inbuf;
502 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
503 msg->buf.length);
504 if (inbuf == NULL) {
505 exit_server("smbd_deferred_open_timer: talloc failed\n");
506 return;
509 /* We leave this message on the queue so the open code can
510 know this is a retry. */
511 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
512 (unsigned long long)mid ));
514 /* Mark the message as processed so this is not
515 * re-processed in error. */
516 msg->processed = true;
518 process_smb(smbd_server_conn, inbuf,
519 msg->buf.length, 0,
520 msg->seqnum, msg->encrypted, &msg->pcd);
522 /* If it's still there and was processed, remove it. */
523 msg = get_deferred_open_message_smb(mid);
524 if (msg && msg->processed) {
525 remove_deferred_open_message_smb(mid);
529 /****************************************************************************
530 Function to push a message onto the tail of a linked list of smb messages ready
531 for processing.
532 ****************************************************************************/
534 static bool push_queued_message(struct smb_request *req,
535 struct timeval request_time,
536 struct timeval end_time,
537 char *private_data, size_t private_len)
539 int msg_len = smb_len(req->inbuf) + 4;
540 struct pending_message_list *msg;
542 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
544 if(msg == NULL) {
545 DEBUG(0,("push_message: malloc fail (1)\n"));
546 return False;
549 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
550 if(msg->buf.data == NULL) {
551 DEBUG(0,("push_message: malloc fail (2)\n"));
552 TALLOC_FREE(msg);
553 return False;
556 msg->request_time = request_time;
557 msg->seqnum = req->seqnum;
558 msg->encrypted = req->encrypted;
559 msg->processed = false;
560 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
562 if (private_data) {
563 msg->private_data = data_blob_talloc(msg, private_data,
564 private_len);
565 if (msg->private_data.data == NULL) {
566 DEBUG(0,("push_message: malloc fail (3)\n"));
567 TALLOC_FREE(msg);
568 return False;
572 msg->te = event_add_timed(smbd_event_context(),
573 msg,
574 end_time,
575 smbd_deferred_open_timer,
576 msg);
577 if (!msg->te) {
578 DEBUG(0,("push_message: event_add_timed failed\n"));
579 TALLOC_FREE(msg);
580 return false;
583 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
585 DEBUG(10,("push_message: pushed message length %u on "
586 "deferred_open_queue\n", (unsigned int)msg_len));
588 return True;
591 /****************************************************************************
592 Function to delete a sharing violation open message by mid.
593 ****************************************************************************/
595 void remove_deferred_open_message_smb(uint64_t mid)
597 struct pending_message_list *pml;
599 if (smbd_server_conn->using_smb2) {
600 remove_deferred_open_message_smb2(smbd_server_conn, mid);
601 return;
604 for (pml = deferred_open_queue; pml; pml = pml->next) {
605 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
606 DEBUG(10,("remove_deferred_open_message_smb: "
607 "deleting mid %llu len %u\n",
608 (unsigned long long)mid,
609 (unsigned int)pml->buf.length ));
610 DLIST_REMOVE(deferred_open_queue, pml);
611 TALLOC_FREE(pml);
612 return;
617 /****************************************************************************
618 Move a sharing violation open retry message to the front of the list and
619 schedule it for immediate processing.
620 ****************************************************************************/
622 void schedule_deferred_open_message_smb(uint64_t mid)
624 struct pending_message_list *pml;
625 int i = 0;
627 if (smbd_server_conn->using_smb2) {
628 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
629 return;
632 for (pml = deferred_open_queue; pml; pml = pml->next) {
633 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
635 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
636 "msg_mid = %llu\n",
637 i++,
638 (unsigned long long)msg_mid ));
640 if (mid == msg_mid) {
641 struct timed_event *te;
643 if (pml->processed) {
644 /* A processed message should not be
645 * rescheduled. */
646 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
647 "message mid %llu was already processed\n",
648 (unsigned long long)msg_mid ));
649 continue;
652 DEBUG(10,("schedule_deferred_open_message_smb: "
653 "scheduling mid %llu\n",
654 (unsigned long long)mid ));
656 te = event_add_timed(smbd_event_context(),
657 pml,
658 timeval_zero(),
659 smbd_deferred_open_timer,
660 pml);
661 if (!te) {
662 DEBUG(10,("schedule_deferred_open_message_smb: "
663 "event_add_timed() failed, "
664 "skipping mid %llu\n",
665 (unsigned long long)msg_mid ));
668 TALLOC_FREE(pml->te);
669 pml->te = te;
670 DLIST_PROMOTE(deferred_open_queue, pml);
671 return;
675 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
676 "find message mid %llu\n",
677 (unsigned long long)mid ));
680 /****************************************************************************
681 Return true if this mid is on the deferred queue and was not yet processed.
682 ****************************************************************************/
684 bool open_was_deferred(uint64_t mid)
686 struct pending_message_list *pml;
688 if (smbd_server_conn->using_smb2) {
689 return open_was_deferred_smb2(smbd_server_conn, mid);
692 for (pml = deferred_open_queue; pml; pml = pml->next) {
693 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
694 return True;
697 return False;
700 /****************************************************************************
701 Return the message queued by this mid.
702 ****************************************************************************/
704 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
706 struct pending_message_list *pml;
708 for (pml = deferred_open_queue; pml; pml = pml->next) {
709 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
710 return pml;
713 return NULL;
716 /****************************************************************************
717 Get the state data queued by this mid.
718 ****************************************************************************/
720 bool get_deferred_open_message_state(struct smb_request *smbreq,
721 struct timeval *p_request_time,
722 void **pp_state)
724 struct pending_message_list *pml;
726 if (smbd_server_conn->using_smb2) {
727 return get_deferred_open_message_state_smb2(smbreq->smb2req,
728 p_request_time,
729 pp_state);
732 pml = get_deferred_open_message_smb(smbreq->mid);
733 if (!pml) {
734 return false;
736 if (p_request_time) {
737 *p_request_time = pml->request_time;
739 if (pp_state) {
740 *pp_state = (void *)pml->private_data.data;
742 return true;
745 /****************************************************************************
746 Function to push a deferred open smb message onto a linked list of local smb
747 messages ready for processing.
748 ****************************************************************************/
750 bool push_deferred_open_message_smb(struct smb_request *req,
751 struct timeval request_time,
752 struct timeval timeout,
753 struct file_id id,
754 char *private_data, size_t priv_len)
756 struct timeval end_time;
758 if (req->smb2req) {
759 return push_deferred_open_message_smb2(req->smb2req,
760 request_time,
761 timeout,
763 private_data,
764 priv_len);
767 if (req->unread_bytes) {
768 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
769 "unread_bytes = %u\n",
770 (unsigned int)req->unread_bytes ));
771 smb_panic("push_deferred_open_message_smb: "
772 "logic error unread_bytes != 0" );
775 end_time = timeval_sum(&request_time, &timeout);
777 DEBUG(10,("push_deferred_open_message_smb: pushing message "
778 "len %u mid %llu timeout time [%u.%06u]\n",
779 (unsigned int) smb_len(req->inbuf)+4,
780 (unsigned long long)req->mid,
781 (unsigned int)end_time.tv_sec,
782 (unsigned int)end_time.tv_usec));
784 return push_queued_message(req, request_time, end_time,
785 private_data, priv_len);
788 struct idle_event {
789 struct timed_event *te;
790 struct timeval interval;
791 char *name;
792 bool (*handler)(const struct timeval *now, void *private_data);
793 void *private_data;
796 static void smbd_idle_event_handler(struct event_context *ctx,
797 struct timed_event *te,
798 struct timeval now,
799 void *private_data)
801 struct idle_event *event =
802 talloc_get_type_abort(private_data, struct idle_event);
804 TALLOC_FREE(event->te);
806 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
807 event->name, event->te));
809 if (!event->handler(&now, event->private_data)) {
810 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
811 event->name, event->te));
812 /* Don't repeat, delete ourselves */
813 TALLOC_FREE(event);
814 return;
817 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
818 event->name, event->te));
820 event->te = event_add_timed(ctx, event,
821 timeval_sum(&now, &event->interval),
822 smbd_idle_event_handler, event);
824 /* We can't do much but fail here. */
825 SMB_ASSERT(event->te != NULL);
828 struct idle_event *event_add_idle(struct event_context *event_ctx,
829 TALLOC_CTX *mem_ctx,
830 struct timeval interval,
831 const char *name,
832 bool (*handler)(const struct timeval *now,
833 void *private_data),
834 void *private_data)
836 struct idle_event *result;
837 struct timeval now = timeval_current();
839 result = TALLOC_P(mem_ctx, struct idle_event);
840 if (result == NULL) {
841 DEBUG(0, ("talloc failed\n"));
842 return NULL;
845 result->interval = interval;
846 result->handler = handler;
847 result->private_data = private_data;
849 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
850 DEBUG(0, ("talloc failed\n"));
851 TALLOC_FREE(result);
852 return NULL;
855 result->te = event_add_timed(event_ctx, result,
856 timeval_sum(&now, &interval),
857 smbd_idle_event_handler, result);
858 if (result->te == NULL) {
859 DEBUG(0, ("event_add_timed failed\n"));
860 TALLOC_FREE(result);
861 return NULL;
864 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
865 return result;
868 static void smbd_sig_term_handler(struct tevent_context *ev,
869 struct tevent_signal *se,
870 int signum,
871 int count,
872 void *siginfo,
873 void *private_data)
875 exit_server_cleanly("termination signal");
878 void smbd_setup_sig_term_handler(void)
880 struct tevent_signal *se;
882 se = tevent_add_signal(smbd_event_context(),
883 smbd_event_context(),
884 SIGTERM, 0,
885 smbd_sig_term_handler,
886 NULL);
887 if (!se) {
888 exit_server("failed to setup SIGTERM handler");
892 static void smbd_sig_hup_handler(struct tevent_context *ev,
893 struct tevent_signal *se,
894 int signum,
895 int count,
896 void *siginfo,
897 void *private_data)
899 struct messaging_context *msg_ctx = talloc_get_type_abort(
900 private_data, struct messaging_context);
901 change_to_root_user();
902 DEBUG(1,("Reloading services after SIGHUP\n"));
903 reload_services(msg_ctx, False);
906 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
907 struct messaging_context *msg_ctx)
909 struct tevent_signal *se;
911 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
912 msg_ctx);
913 if (!se) {
914 exit_server("failed to setup SIGHUP handler");
918 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
920 fd_set r_fds, w_fds;
921 int selrtn;
922 struct timeval to;
923 int maxfd = 0;
925 to.tv_sec = SMBD_SELECT_TIMEOUT;
926 to.tv_usec = 0;
929 * Setup the select fd sets.
932 FD_ZERO(&r_fds);
933 FD_ZERO(&w_fds);
936 * Are there any timed events waiting ? If so, ensure we don't
937 * select for longer than it would take to wait for them.
941 struct timeval now;
942 GetTimeOfDay(&now);
944 event_add_to_select_args(smbd_event_context(), &now,
945 &r_fds, &w_fds, &to, &maxfd);
948 /* Process a signal and timed events now... */
949 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
950 return NT_STATUS_RETRY;
954 int sav;
955 START_PROFILE(smbd_idle);
957 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
958 sav = errno;
960 END_PROFILE(smbd_idle);
961 errno = sav;
964 if ((conn->smb1.echo_handler.trusted_fd != -1)
965 && FD_ISSET(conn->sock, &r_fds)
966 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
968 * Prefer to read pending requests from the echo handler. To
969 * quote Jeremy (da70f8ab1): This is a hack of monstrous
970 * proportions...
972 FD_CLR(conn->sock, &r_fds);
975 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
976 return NT_STATUS_RETRY;
979 /* Check if error */
980 if (selrtn == -1) {
981 /* something is wrong. Maybe the socket is dead? */
982 return map_nt_error_from_unix(errno);
985 /* Did we timeout ? */
986 if (selrtn == 0) {
987 return NT_STATUS_RETRY;
990 /* should not be reached */
991 return NT_STATUS_INTERNAL_ERROR;
995 * Only allow 5 outstanding trans requests. We're allocating memory, so
996 * prevent a DoS.
999 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1001 int count = 0;
1002 for (; list != NULL; list = list->next) {
1004 if (list->mid == mid) {
1005 return NT_STATUS_INVALID_PARAMETER;
1008 count += 1;
1010 if (count > 5) {
1011 return NT_STATUS_INSUFFICIENT_RESOURCES;
1014 return NT_STATUS_OK;
1018 These flags determine some of the permissions required to do an operation
1020 Note that I don't set NEED_WRITE on some write operations because they
1021 are used by some brain-dead clients when printing, and I don't want to
1022 force write permissions on print services.
1024 #define AS_USER (1<<0)
1025 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1026 #define TIME_INIT (1<<2)
1027 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1028 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1029 #define DO_CHDIR (1<<6)
1032 define a list of possible SMB messages and their corresponding
1033 functions. Any message that has a NULL function is unimplemented -
1034 please feel free to contribute implementations!
1036 static const struct smb_message_struct {
1037 const char *name;
1038 void (*fn)(struct smb_request *req);
1039 int flags;
1040 } smb_messages[256] = {
1042 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1043 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1044 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1045 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1046 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1047 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1048 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1049 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1050 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1051 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1052 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1053 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1054 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1055 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1056 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1057 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1058 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1059 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1060 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1061 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1062 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1063 /* 0x15 */ { NULL, NULL, 0 },
1064 /* 0x16 */ { NULL, NULL, 0 },
1065 /* 0x17 */ { NULL, NULL, 0 },
1066 /* 0x18 */ { NULL, NULL, 0 },
1067 /* 0x19 */ { NULL, NULL, 0 },
1068 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1069 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1070 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1071 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1072 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1073 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1074 /* 0x20 */ { "SMBwritec", NULL,0},
1075 /* 0x21 */ { NULL, NULL, 0 },
1076 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1077 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1078 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1079 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1080 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1081 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1082 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1083 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1084 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1085 /* 0x2b */ { "SMBecho",reply_echo,0},
1086 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1087 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1088 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1089 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1090 /* 0x30 */ { NULL, NULL, 0 },
1091 /* 0x31 */ { NULL, NULL, 0 },
1092 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1093 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1094 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1095 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1096 /* 0x36 */ { NULL, NULL, 0 },
1097 /* 0x37 */ { NULL, NULL, 0 },
1098 /* 0x38 */ { NULL, NULL, 0 },
1099 /* 0x39 */ { NULL, NULL, 0 },
1100 /* 0x3a */ { NULL, NULL, 0 },
1101 /* 0x3b */ { NULL, NULL, 0 },
1102 /* 0x3c */ { NULL, NULL, 0 },
1103 /* 0x3d */ { NULL, NULL, 0 },
1104 /* 0x3e */ { NULL, NULL, 0 },
1105 /* 0x3f */ { NULL, NULL, 0 },
1106 /* 0x40 */ { NULL, NULL, 0 },
1107 /* 0x41 */ { NULL, NULL, 0 },
1108 /* 0x42 */ { NULL, NULL, 0 },
1109 /* 0x43 */ { NULL, NULL, 0 },
1110 /* 0x44 */ { NULL, NULL, 0 },
1111 /* 0x45 */ { NULL, NULL, 0 },
1112 /* 0x46 */ { NULL, NULL, 0 },
1113 /* 0x47 */ { NULL, NULL, 0 },
1114 /* 0x48 */ { NULL, NULL, 0 },
1115 /* 0x49 */ { NULL, NULL, 0 },
1116 /* 0x4a */ { NULL, NULL, 0 },
1117 /* 0x4b */ { NULL, NULL, 0 },
1118 /* 0x4c */ { NULL, NULL, 0 },
1119 /* 0x4d */ { NULL, NULL, 0 },
1120 /* 0x4e */ { NULL, NULL, 0 },
1121 /* 0x4f */ { NULL, NULL, 0 },
1122 /* 0x50 */ { NULL, NULL, 0 },
1123 /* 0x51 */ { NULL, NULL, 0 },
1124 /* 0x52 */ { NULL, NULL, 0 },
1125 /* 0x53 */ { NULL, NULL, 0 },
1126 /* 0x54 */ { NULL, NULL, 0 },
1127 /* 0x55 */ { NULL, NULL, 0 },
1128 /* 0x56 */ { NULL, NULL, 0 },
1129 /* 0x57 */ { NULL, NULL, 0 },
1130 /* 0x58 */ { NULL, NULL, 0 },
1131 /* 0x59 */ { NULL, NULL, 0 },
1132 /* 0x5a */ { NULL, NULL, 0 },
1133 /* 0x5b */ { NULL, NULL, 0 },
1134 /* 0x5c */ { NULL, NULL, 0 },
1135 /* 0x5d */ { NULL, NULL, 0 },
1136 /* 0x5e */ { NULL, NULL, 0 },
1137 /* 0x5f */ { NULL, NULL, 0 },
1138 /* 0x60 */ { NULL, NULL, 0 },
1139 /* 0x61 */ { NULL, NULL, 0 },
1140 /* 0x62 */ { NULL, NULL, 0 },
1141 /* 0x63 */ { NULL, NULL, 0 },
1142 /* 0x64 */ { NULL, NULL, 0 },
1143 /* 0x65 */ { NULL, NULL, 0 },
1144 /* 0x66 */ { NULL, NULL, 0 },
1145 /* 0x67 */ { NULL, NULL, 0 },
1146 /* 0x68 */ { NULL, NULL, 0 },
1147 /* 0x69 */ { NULL, NULL, 0 },
1148 /* 0x6a */ { NULL, NULL, 0 },
1149 /* 0x6b */ { NULL, NULL, 0 },
1150 /* 0x6c */ { NULL, NULL, 0 },
1151 /* 0x6d */ { NULL, NULL, 0 },
1152 /* 0x6e */ { NULL, NULL, 0 },
1153 /* 0x6f */ { NULL, NULL, 0 },
1154 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1155 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1156 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1157 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1158 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1159 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1160 /* 0x76 */ { NULL, NULL, 0 },
1161 /* 0x77 */ { NULL, NULL, 0 },
1162 /* 0x78 */ { NULL, NULL, 0 },
1163 /* 0x79 */ { NULL, NULL, 0 },
1164 /* 0x7a */ { NULL, NULL, 0 },
1165 /* 0x7b */ { NULL, NULL, 0 },
1166 /* 0x7c */ { NULL, NULL, 0 },
1167 /* 0x7d */ { NULL, NULL, 0 },
1168 /* 0x7e */ { NULL, NULL, 0 },
1169 /* 0x7f */ { NULL, NULL, 0 },
1170 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1171 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1172 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1173 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1174 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1175 /* 0x85 */ { NULL, NULL, 0 },
1176 /* 0x86 */ { NULL, NULL, 0 },
1177 /* 0x87 */ { NULL, NULL, 0 },
1178 /* 0x88 */ { NULL, NULL, 0 },
1179 /* 0x89 */ { NULL, NULL, 0 },
1180 /* 0x8a */ { NULL, NULL, 0 },
1181 /* 0x8b */ { NULL, NULL, 0 },
1182 /* 0x8c */ { NULL, NULL, 0 },
1183 /* 0x8d */ { NULL, NULL, 0 },
1184 /* 0x8e */ { NULL, NULL, 0 },
1185 /* 0x8f */ { NULL, NULL, 0 },
1186 /* 0x90 */ { NULL, NULL, 0 },
1187 /* 0x91 */ { NULL, NULL, 0 },
1188 /* 0x92 */ { NULL, NULL, 0 },
1189 /* 0x93 */ { NULL, NULL, 0 },
1190 /* 0x94 */ { NULL, NULL, 0 },
1191 /* 0x95 */ { NULL, NULL, 0 },
1192 /* 0x96 */ { NULL, NULL, 0 },
1193 /* 0x97 */ { NULL, NULL, 0 },
1194 /* 0x98 */ { NULL, NULL, 0 },
1195 /* 0x99 */ { NULL, NULL, 0 },
1196 /* 0x9a */ { NULL, NULL, 0 },
1197 /* 0x9b */ { NULL, NULL, 0 },
1198 /* 0x9c */ { NULL, NULL, 0 },
1199 /* 0x9d */ { NULL, NULL, 0 },
1200 /* 0x9e */ { NULL, NULL, 0 },
1201 /* 0x9f */ { NULL, NULL, 0 },
1202 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1203 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1204 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1205 /* 0xa3 */ { NULL, NULL, 0 },
1206 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1207 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1208 /* 0xa6 */ { NULL, NULL, 0 },
1209 /* 0xa7 */ { NULL, NULL, 0 },
1210 /* 0xa8 */ { NULL, NULL, 0 },
1211 /* 0xa9 */ { NULL, NULL, 0 },
1212 /* 0xaa */ { NULL, NULL, 0 },
1213 /* 0xab */ { NULL, NULL, 0 },
1214 /* 0xac */ { NULL, NULL, 0 },
1215 /* 0xad */ { NULL, NULL, 0 },
1216 /* 0xae */ { NULL, NULL, 0 },
1217 /* 0xaf */ { NULL, NULL, 0 },
1218 /* 0xb0 */ { NULL, NULL, 0 },
1219 /* 0xb1 */ { NULL, NULL, 0 },
1220 /* 0xb2 */ { NULL, NULL, 0 },
1221 /* 0xb3 */ { NULL, NULL, 0 },
1222 /* 0xb4 */ { NULL, NULL, 0 },
1223 /* 0xb5 */ { NULL, NULL, 0 },
1224 /* 0xb6 */ { NULL, NULL, 0 },
1225 /* 0xb7 */ { NULL, NULL, 0 },
1226 /* 0xb8 */ { NULL, NULL, 0 },
1227 /* 0xb9 */ { NULL, NULL, 0 },
1228 /* 0xba */ { NULL, NULL, 0 },
1229 /* 0xbb */ { NULL, NULL, 0 },
1230 /* 0xbc */ { NULL, NULL, 0 },
1231 /* 0xbd */ { NULL, NULL, 0 },
1232 /* 0xbe */ { NULL, NULL, 0 },
1233 /* 0xbf */ { NULL, NULL, 0 },
1234 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1235 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1236 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1237 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1238 /* 0xc4 */ { NULL, NULL, 0 },
1239 /* 0xc5 */ { NULL, NULL, 0 },
1240 /* 0xc6 */ { NULL, NULL, 0 },
1241 /* 0xc7 */ { NULL, NULL, 0 },
1242 /* 0xc8 */ { NULL, NULL, 0 },
1243 /* 0xc9 */ { NULL, NULL, 0 },
1244 /* 0xca */ { NULL, NULL, 0 },
1245 /* 0xcb */ { NULL, NULL, 0 },
1246 /* 0xcc */ { NULL, NULL, 0 },
1247 /* 0xcd */ { NULL, NULL, 0 },
1248 /* 0xce */ { NULL, NULL, 0 },
1249 /* 0xcf */ { NULL, NULL, 0 },
1250 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1251 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1252 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1253 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1254 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1255 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1256 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1257 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1258 /* 0xd8 */ { NULL, NULL, 0 },
1259 /* 0xd9 */ { NULL, NULL, 0 },
1260 /* 0xda */ { NULL, NULL, 0 },
1261 /* 0xdb */ { NULL, NULL, 0 },
1262 /* 0xdc */ { NULL, NULL, 0 },
1263 /* 0xdd */ { NULL, NULL, 0 },
1264 /* 0xde */ { NULL, NULL, 0 },
1265 /* 0xdf */ { NULL, NULL, 0 },
1266 /* 0xe0 */ { NULL, NULL, 0 },
1267 /* 0xe1 */ { NULL, NULL, 0 },
1268 /* 0xe2 */ { NULL, NULL, 0 },
1269 /* 0xe3 */ { NULL, NULL, 0 },
1270 /* 0xe4 */ { NULL, NULL, 0 },
1271 /* 0xe5 */ { NULL, NULL, 0 },
1272 /* 0xe6 */ { NULL, NULL, 0 },
1273 /* 0xe7 */ { NULL, NULL, 0 },
1274 /* 0xe8 */ { NULL, NULL, 0 },
1275 /* 0xe9 */ { NULL, NULL, 0 },
1276 /* 0xea */ { NULL, NULL, 0 },
1277 /* 0xeb */ { NULL, NULL, 0 },
1278 /* 0xec */ { NULL, NULL, 0 },
1279 /* 0xed */ { NULL, NULL, 0 },
1280 /* 0xee */ { NULL, NULL, 0 },
1281 /* 0xef */ { NULL, NULL, 0 },
1282 /* 0xf0 */ { NULL, NULL, 0 },
1283 /* 0xf1 */ { NULL, NULL, 0 },
1284 /* 0xf2 */ { NULL, NULL, 0 },
1285 /* 0xf3 */ { NULL, NULL, 0 },
1286 /* 0xf4 */ { NULL, NULL, 0 },
1287 /* 0xf5 */ { NULL, NULL, 0 },
1288 /* 0xf6 */ { NULL, NULL, 0 },
1289 /* 0xf7 */ { NULL, NULL, 0 },
1290 /* 0xf8 */ { NULL, NULL, 0 },
1291 /* 0xf9 */ { NULL, NULL, 0 },
1292 /* 0xfa */ { NULL, NULL, 0 },
1293 /* 0xfb */ { NULL, NULL, 0 },
1294 /* 0xfc */ { NULL, NULL, 0 },
1295 /* 0xfd */ { NULL, NULL, 0 },
1296 /* 0xfe */ { NULL, NULL, 0 },
1297 /* 0xff */ { NULL, NULL, 0 }
1301 /*******************************************************************
1302 allocate and initialize a reply packet
1303 ********************************************************************/
1305 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1306 const char *inbuf, char **outbuf, uint8_t num_words,
1307 uint32_t num_bytes)
1310 * Protect against integer wrap
1312 if ((num_bytes > 0xffffff)
1313 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1314 char *msg;
1315 if (asprintf(&msg, "num_bytes too large: %u",
1316 (unsigned)num_bytes) == -1) {
1317 msg = CONST_DISCARD(char *, "num_bytes too large");
1319 smb_panic(msg);
1322 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1323 smb_size + num_words*2 + num_bytes);
1324 if (*outbuf == NULL) {
1325 return false;
1328 construct_reply_common(req, inbuf, *outbuf);
1329 srv_set_message(*outbuf, num_words, num_bytes, false);
1331 * Zero out the word area, the caller has to take care of the bcc area
1332 * himself
1334 if (num_words != 0) {
1335 memset(*outbuf + smb_vwv0, 0, num_words*2);
1338 return true;
1341 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1343 char *outbuf;
1344 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1345 num_bytes)) {
1346 smb_panic("could not allocate output buffer\n");
1348 req->outbuf = (uint8_t *)outbuf;
1352 /*******************************************************************
1353 Dump a packet to a file.
1354 ********************************************************************/
1356 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1358 int fd, i;
1359 char *fname = NULL;
1360 if (DEBUGLEVEL < 50) {
1361 return;
1364 if (len < 4) len = smb_len(data)+4;
1365 for (i=1;i<100;i++) {
1366 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1367 type ? "req" : "resp") == -1) {
1368 return;
1370 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1371 if (fd != -1 || errno != EEXIST) break;
1373 if (fd != -1) {
1374 ssize_t ret = write(fd, data, len);
1375 if (ret != len)
1376 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1377 close(fd);
1378 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1380 SAFE_FREE(fname);
1383 /****************************************************************************
1384 Prepare everything for calling the actual request function, and potentially
1385 call the request function via the "new" interface.
1387 Return False if the "legacy" function needs to be called, everything is
1388 prepared.
1390 Return True if we're done.
1392 I know this API sucks, but it is the one with the least code change I could
1393 find.
1394 ****************************************************************************/
1396 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1398 int flags;
1399 uint16 session_tag;
1400 connection_struct *conn = NULL;
1401 struct smbd_server_connection *sconn = req->sconn;
1403 errno = 0;
1405 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1406 * so subtract 4 from it. */
1407 if (!valid_smb_header(req->inbuf)
1408 || (size < (smb_size - 4))) {
1409 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1410 smb_len(req->inbuf)));
1411 exit_server_cleanly("Non-SMB packet");
1414 if (smb_messages[type].fn == NULL) {
1415 DEBUG(0,("Unknown message type %d!\n",type));
1416 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1417 reply_unknown_new(req, type);
1418 return NULL;
1421 flags = smb_messages[type].flags;
1423 /* In share mode security we must ignore the vuid. */
1424 session_tag = (lp_security() == SEC_SHARE)
1425 ? UID_FIELD_INVALID : req->vuid;
1426 conn = req->conn;
1428 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1429 (int)sys_getpid(), (unsigned long)conn));
1431 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1433 /* Ensure this value is replaced in the incoming packet. */
1434 SSVAL(req->inbuf,smb_uid,session_tag);
1437 * Ensure the correct username is in current_user_info. This is a
1438 * really ugly bugfix for problems with multiple session_setup_and_X's
1439 * being done and allowing %U and %G substitutions to work correctly.
1440 * There is a reason this code is done here, don't move it unless you
1441 * know what you're doing... :-).
1442 * JRA.
1445 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1446 user_struct *vuser = NULL;
1448 sconn->smb1.sessions.last_session_tag = session_tag;
1449 if(session_tag != UID_FIELD_INVALID) {
1450 vuser = get_valid_user_struct(sconn, session_tag);
1451 if (vuser) {
1452 set_current_user_info(
1453 vuser->server_info->sanitized_username,
1454 vuser->server_info->unix_name,
1455 vuser->server_info->info3->base.domain.string);
1460 /* Does this call need to be run as the connected user? */
1461 if (flags & AS_USER) {
1463 /* Does this call need a valid tree connection? */
1464 if (!conn) {
1466 * Amazingly, the error code depends on the command
1467 * (from Samba4).
1469 if (type == SMBntcreateX) {
1470 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1471 } else {
1472 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1474 return NULL;
1477 if (!change_to_user(conn,session_tag)) {
1478 DEBUG(0, ("Error: Could not change to user. Removing "
1479 "deferred open, mid=%llu.\n",
1480 (unsigned long long)req->mid));
1481 reply_force_doserror(req, ERRSRV, ERRbaduid);
1482 return conn;
1485 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1487 /* Does it need write permission? */
1488 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1489 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1490 return conn;
1493 /* IPC services are limited */
1494 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1495 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1496 return conn;
1498 } else {
1499 /* This call needs to be run as root */
1500 change_to_root_user();
1503 /* load service specific parameters */
1504 if (conn) {
1505 if (req->encrypted) {
1506 conn->encrypted_tid = true;
1507 /* encrypted required from now on. */
1508 conn->encrypt_level = Required;
1509 } else if (ENCRYPTION_REQUIRED(conn)) {
1510 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1511 exit_server_cleanly("encryption required "
1512 "on connection");
1513 return conn;
1517 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1518 (flags & (AS_USER|DO_CHDIR)
1519 ?True:False))) {
1520 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1521 return conn;
1523 conn->num_smb_operations++;
1526 /* does this protocol need to be run as guest? */
1527 if ((flags & AS_GUEST)
1528 && (!change_to_guest() ||
1529 !check_access(sconn->sock, lp_hostsallow(-1),
1530 lp_hostsdeny(-1)))) {
1531 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 return conn;
1535 smb_messages[type].fn(req);
1536 return req->conn;
1539 /****************************************************************************
1540 Construct a reply to the incoming packet.
1541 ****************************************************************************/
1543 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1544 uint32_t seqnum, bool encrypted,
1545 struct smb_perfcount_data *deferred_pcd)
1547 connection_struct *conn;
1548 struct smb_request *req;
1550 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1551 smb_panic("could not allocate smb_request");
1554 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1555 unread_bytes, encrypted, seqnum)) {
1556 exit_server_cleanly("Invalid SMB request");
1559 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1561 /* we popped this message off the queue - keep original perf data */
1562 if (deferred_pcd)
1563 req->pcd = *deferred_pcd;
1564 else {
1565 SMB_PERFCOUNT_START(&req->pcd);
1566 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1567 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1570 conn = switch_message(req->cmd, req, size);
1572 if (req->unread_bytes) {
1573 /* writeX failed. drain socket. */
1574 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1575 req->unread_bytes) {
1576 smb_panic("failed to drain pending bytes");
1578 req->unread_bytes = 0;
1581 if (req->done) {
1582 TALLOC_FREE(req);
1583 return;
1586 if (req->outbuf == NULL) {
1587 return;
1590 if (CVAL(req->outbuf,0) == 0) {
1591 show_msg((char *)req->outbuf);
1594 if (!srv_send_smb(req->sconn->sock,
1595 (char *)req->outbuf,
1596 true, req->seqnum+1,
1597 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1598 &req->pcd)) {
1599 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1602 TALLOC_FREE(req);
1604 return;
1607 /****************************************************************************
1608 Process an smb from the client
1609 ****************************************************************************/
1610 static void process_smb(struct smbd_server_connection *conn,
1611 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1612 uint32_t seqnum, bool encrypted,
1613 struct smb_perfcount_data *deferred_pcd)
1615 int msg_type = CVAL(inbuf,0);
1617 DO_PROFILE_INC(smb_count);
1619 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1620 smb_len(inbuf) ) );
1621 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1622 (int)nread,
1623 (unsigned int)unread_bytes ));
1625 if (msg_type != 0) {
1627 * NetBIOS session request, keepalive, etc.
1629 reply_special(conn, (char *)inbuf);
1630 goto done;
1633 if (smbd_server_conn->using_smb2) {
1634 /* At this point we're not really using smb2,
1635 * we make the decision here.. */
1636 if (smbd_is_smb2_header(inbuf, nread)) {
1637 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1638 return;
1639 } else if (nread >= smb_size && valid_smb_header(inbuf)
1640 && CVAL(inbuf, smb_com) != 0x72) {
1641 /* This is a non-negprot SMB1 packet.
1642 Disable SMB2 from now on. */
1643 smbd_server_conn->using_smb2 = false;
1647 show_msg((char *)inbuf);
1649 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1650 trans_num++;
1652 done:
1653 conn->smb1.num_requests++;
1655 /* The timeout_processing function isn't run nearly
1656 often enough to implement 'max log size' without
1657 overrunning the size of the file by many megabytes.
1658 This is especially true if we are running at debug
1659 level 10. Checking every 50 SMBs is a nice
1660 tradeoff of performance vs log file size overrun. */
1662 if ((conn->smb1.num_requests % 50) == 0 &&
1663 need_to_check_log_size()) {
1664 change_to_root_user();
1665 check_log_size();
1669 /****************************************************************************
1670 Return a string containing the function name of a SMB command.
1671 ****************************************************************************/
1673 const char *smb_fn_name(int type)
1675 const char *unknown_name = "SMBunknown";
1677 if (smb_messages[type].name == NULL)
1678 return(unknown_name);
1680 return(smb_messages[type].name);
1683 /****************************************************************************
1684 Helper functions for contruct_reply.
1685 ****************************************************************************/
1687 void add_to_common_flags2(uint32 v)
1689 common_flags2 |= v;
1692 void remove_from_common_flags2(uint32 v)
1694 common_flags2 &= ~v;
1697 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1698 char *outbuf)
1700 srv_set_message(outbuf,0,0,false);
1702 SCVAL(outbuf, smb_com, req->cmd);
1703 SIVAL(outbuf,smb_rcls,0);
1704 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1705 SSVAL(outbuf,smb_flg2,
1706 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1707 common_flags2);
1708 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1710 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1711 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1712 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1713 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1716 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1718 construct_reply_common(req, (char *)req->inbuf, outbuf);
1722 * How many bytes have we already accumulated up to the current wct field
1723 * offset?
1726 size_t req_wct_ofs(struct smb_request *req)
1728 size_t buf_size;
1730 if (req->chain_outbuf == NULL) {
1731 return smb_wct - 4;
1733 buf_size = talloc_get_size(req->chain_outbuf);
1734 if ((buf_size % 4) != 0) {
1735 buf_size += (4 - (buf_size % 4));
1737 return buf_size - 4;
1741 * Hack around reply_nterror & friends not being aware of chained requests,
1742 * generating illegal (i.e. wct==0) chain replies.
1745 static void fixup_chain_error_packet(struct smb_request *req)
1747 uint8_t *outbuf = req->outbuf;
1748 req->outbuf = NULL;
1749 reply_outbuf(req, 2, 0);
1750 memcpy(req->outbuf, outbuf, smb_wct);
1751 TALLOC_FREE(outbuf);
1752 SCVAL(req->outbuf, smb_vwv0, 0xff);
1756 * @brief Find the smb_cmd offset of the last command pushed
1757 * @param[in] buf The buffer we're building up
1758 * @retval Where can we put our next andx cmd?
1760 * While chaining requests, the "next" request we're looking at needs to put
1761 * its SMB_Command before the data the previous request already built up added
1762 * to the chain. Find the offset to the place where we have to put our cmd.
1765 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1767 uint8_t cmd;
1768 size_t ofs;
1770 cmd = CVAL(buf, smb_com);
1772 SMB_ASSERT(is_andx_req(cmd));
1774 ofs = smb_vwv0;
1776 while (CVAL(buf, ofs) != 0xff) {
1778 if (!is_andx_req(CVAL(buf, ofs))) {
1779 return false;
1783 * ofs is from start of smb header, so add the 4 length
1784 * bytes. The next cmd is right after the wct field.
1786 ofs = SVAL(buf, ofs+2) + 4 + 1;
1788 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1791 *pofs = ofs;
1792 return true;
1796 * @brief Do the smb chaining at a buffer level
1797 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1798 * @param[in] smb_command The command that we want to issue
1799 * @param[in] wct How many words?
1800 * @param[in] vwv The words, already in network order
1801 * @param[in] bytes_alignment How shall we align "bytes"?
1802 * @param[in] num_bytes How many bytes?
1803 * @param[in] bytes The data the request ships
1805 * smb_splice_chain() adds the vwv and bytes to the request already present in
1806 * *poutbuf.
1809 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1810 uint8_t wct, const uint16_t *vwv,
1811 size_t bytes_alignment,
1812 uint32_t num_bytes, const uint8_t *bytes)
1814 uint8_t *outbuf;
1815 size_t old_size, new_size;
1816 size_t ofs;
1817 size_t chain_padding = 0;
1818 size_t bytes_padding = 0;
1819 bool first_request;
1821 old_size = talloc_get_size(*poutbuf);
1824 * old_size == smb_wct means we're pushing the first request in for
1825 * libsmb/
1828 first_request = (old_size == smb_wct);
1830 if (!first_request && ((old_size % 4) != 0)) {
1832 * Align the wct field of subsequent requests to a 4-byte
1833 * boundary
1835 chain_padding = 4 - (old_size % 4);
1839 * After the old request comes the new wct field (1 byte), the vwv's
1840 * and the num_bytes field. After at we might need to align the bytes
1841 * given to us to "bytes_alignment", increasing the num_bytes value.
1844 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1846 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1847 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1850 new_size += bytes_padding + num_bytes;
1852 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1853 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1854 (unsigned)new_size));
1855 return false;
1858 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1859 if (outbuf == NULL) {
1860 DEBUG(0, ("talloc failed\n"));
1861 return false;
1863 *poutbuf = outbuf;
1865 if (first_request) {
1866 SCVAL(outbuf, smb_com, smb_command);
1867 } else {
1868 size_t andx_cmd_ofs;
1870 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1871 DEBUG(1, ("invalid command chain\n"));
1872 *poutbuf = TALLOC_REALLOC_ARRAY(
1873 NULL, *poutbuf, uint8_t, old_size);
1874 return false;
1877 if (chain_padding != 0) {
1878 memset(outbuf + old_size, 0, chain_padding);
1879 old_size += chain_padding;
1882 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1883 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1886 ofs = old_size;
1889 * Push the chained request:
1891 * wct field
1894 SCVAL(outbuf, ofs, wct);
1895 ofs += 1;
1898 * vwv array
1901 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1902 ofs += sizeof(uint16_t) * wct;
1905 * bcc (byte count)
1908 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1909 ofs += sizeof(uint16_t);
1912 * padding
1915 if (bytes_padding != 0) {
1916 memset(outbuf + ofs, 0, bytes_padding);
1917 ofs += bytes_padding;
1921 * The bytes field
1924 memcpy(outbuf + ofs, bytes, num_bytes);
1926 return true;
1929 /****************************************************************************
1930 Construct a chained reply and add it to the already made reply
1931 ****************************************************************************/
1933 void chain_reply(struct smb_request *req)
1935 size_t smblen = smb_len(req->inbuf);
1936 size_t already_used, length_needed;
1937 uint8_t chain_cmd;
1938 uint32_t chain_offset; /* uint32_t to avoid overflow */
1940 uint8_t wct;
1941 uint16_t *vwv;
1942 uint16_t buflen;
1943 uint8_t *buf;
1945 if (IVAL(req->outbuf, smb_rcls) != 0) {
1946 fixup_chain_error_packet(req);
1950 * Any of the AndX requests and replies have at least a wct of
1951 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1952 * beginning of the SMB header to the next wct field.
1954 * None of the AndX requests put anything valuable in vwv[0] and [1],
1955 * so we can overwrite it here to form the chain.
1958 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1959 if (req->chain_outbuf == NULL) {
1960 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1961 req, req->outbuf, uint8_t,
1962 smb_len(req->outbuf) + 4);
1963 if (req->chain_outbuf == NULL) {
1964 smb_panic("talloc failed");
1967 req->outbuf = NULL;
1968 goto error;
1972 * Here we assume that this is the end of the chain. For that we need
1973 * to set "next command" to 0xff and the offset to 0. If we later find
1974 * more commands in the chain, this will be overwritten again.
1977 SCVAL(req->outbuf, smb_vwv0, 0xff);
1978 SCVAL(req->outbuf, smb_vwv0+1, 0);
1979 SSVAL(req->outbuf, smb_vwv1, 0);
1981 if (req->chain_outbuf == NULL) {
1983 * In req->chain_outbuf we collect all the replies. Start the
1984 * chain by copying in the first reply.
1986 * We do the realloc because later on we depend on
1987 * talloc_get_size to determine the length of
1988 * chain_outbuf. The reply_xxx routines might have
1989 * over-allocated (reply_pipe_read_and_X used to be such an
1990 * example).
1992 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1993 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1994 if (req->chain_outbuf == NULL) {
1995 smb_panic("talloc failed");
1997 req->outbuf = NULL;
1998 } else {
2000 * Update smb headers where subsequent chained commands
2001 * may have updated them.
2003 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2004 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2006 if (!smb_splice_chain(&req->chain_outbuf,
2007 CVAL(req->outbuf, smb_com),
2008 CVAL(req->outbuf, smb_wct),
2009 (uint16_t *)(req->outbuf + smb_vwv),
2010 0, smb_buflen(req->outbuf),
2011 (uint8_t *)smb_buf(req->outbuf))) {
2012 goto error;
2014 TALLOC_FREE(req->outbuf);
2018 * We use the old request's vwv field to grab the next chained command
2019 * and offset into the chained fields.
2022 chain_cmd = CVAL(req->vwv+0, 0);
2023 chain_offset = SVAL(req->vwv+1, 0);
2025 if (chain_cmd == 0xff) {
2027 * End of chain, no more requests from the client. So ship the
2028 * replies.
2030 smb_setlen((char *)(req->chain_outbuf),
2031 talloc_get_size(req->chain_outbuf) - 4);
2033 if (!srv_send_smb(req->sconn->sock, (char *)req->chain_outbuf,
2034 true, req->seqnum+1,
2035 IS_CONN_ENCRYPTED(req->conn)
2036 ||req->encrypted,
2037 &req->pcd)) {
2038 exit_server_cleanly("chain_reply: srv_send_smb "
2039 "failed.");
2041 TALLOC_FREE(req->chain_outbuf);
2042 req->done = true;
2043 return;
2046 /* add a new perfcounter for this element of chain */
2047 SMB_PERFCOUNT_ADD(&req->pcd);
2048 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2049 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2052 * Check if the client tries to fool us. The request so far uses the
2053 * space to the end of the byte buffer in the request just
2054 * processed. The chain_offset can't point into that area. If that was
2055 * the case, we could end up with an endless processing of the chain,
2056 * we would always handle the same request.
2059 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2060 if (chain_offset < already_used) {
2061 goto error;
2065 * Next check: Make sure the chain offset does not point beyond the
2066 * overall smb request length.
2069 length_needed = chain_offset+1; /* wct */
2070 if (length_needed > smblen) {
2071 goto error;
2075 * Now comes the pointer magic. Goal here is to set up req->vwv and
2076 * req->buf correctly again to be able to call the subsequent
2077 * switch_message(). The chain offset (the former vwv[1]) points at
2078 * the new wct field.
2081 wct = CVAL(smb_base(req->inbuf), chain_offset);
2084 * Next consistency check: Make the new vwv array fits in the overall
2085 * smb request.
2088 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2089 if (length_needed > smblen) {
2090 goto error;
2092 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2095 * Now grab the new byte buffer....
2098 buflen = SVAL(vwv+wct, 0);
2101 * .. and check that it fits.
2104 length_needed += buflen;
2105 if (length_needed > smblen) {
2106 goto error;
2108 buf = (uint8_t *)(vwv+wct+1);
2110 req->cmd = chain_cmd;
2111 req->wct = wct;
2112 req->vwv = vwv;
2113 req->buflen = buflen;
2114 req->buf = buf;
2116 switch_message(chain_cmd, req, smblen);
2118 if (req->outbuf == NULL) {
2120 * This happens if the chained command has suspended itself or
2121 * if it has called srv_send_smb() itself.
2123 return;
2127 * We end up here if the chained command was not itself chained or
2128 * suspended, but for example a close() command. We now need to splice
2129 * the chained commands' outbuf into the already built up chain_outbuf
2130 * and ship the result.
2132 goto done;
2134 error:
2136 * We end up here if there's any error in the chain syntax. Report a
2137 * DOS error, just like Windows does.
2139 reply_force_doserror(req, ERRSRV, ERRerror);
2140 fixup_chain_error_packet(req);
2142 done:
2144 * This scary statement intends to set the
2145 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2146 * to the value req->outbuf carries
2148 SSVAL(req->chain_outbuf, smb_flg2,
2149 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2150 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2153 * Transfer the error codes from the subrequest to the main one
2155 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2156 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2158 if (!smb_splice_chain(&req->chain_outbuf,
2159 CVAL(req->outbuf, smb_com),
2160 CVAL(req->outbuf, smb_wct),
2161 (uint16_t *)(req->outbuf + smb_vwv),
2162 0, smb_buflen(req->outbuf),
2163 (uint8_t *)smb_buf(req->outbuf))) {
2164 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2166 TALLOC_FREE(req->outbuf);
2168 smb_setlen((char *)(req->chain_outbuf),
2169 talloc_get_size(req->chain_outbuf) - 4);
2171 show_msg((char *)(req->chain_outbuf));
2173 if (!srv_send_smb(req->sconn->sock, (char *)req->chain_outbuf,
2174 true, req->seqnum+1,
2175 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2176 &req->pcd)) {
2177 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2179 TALLOC_FREE(req->chain_outbuf);
2180 req->done = true;
2183 /****************************************************************************
2184 Check if services need reloading.
2185 ****************************************************************************/
2187 static void check_reload(struct messaging_context *msg_ctx, time_t t)
2189 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2191 if(last_smb_conf_reload_time == 0) {
2192 last_smb_conf_reload_time = t;
2193 /* Our printing subsystem might not be ready at smbd start up.
2194 Then no printer is available till the first printers check
2195 is performed. A lower initial interval circumvents this. */
2196 if ( printcap_cache_time > 60 )
2197 last_printer_reload_time = t - printcap_cache_time + 60;
2198 else
2199 last_printer_reload_time = t;
2202 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2203 /* randomize over 60 second the printcap reload to avoid all
2204 * process hitting cupsd at the same time */
2205 int time_range = 60;
2207 last_printer_reload_time += random() % time_range;
2208 mypid = getpid();
2211 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2212 reload_services(msg_ctx, True);
2213 last_smb_conf_reload_time = t;
2216 /* 'printcap cache time = 0' disable the feature */
2218 if ( printcap_cache_time != 0 )
2220 /* see if it's time to reload or if the clock has been set back */
2222 if ( (t >= last_printer_reload_time+printcap_cache_time)
2223 || (t-last_printer_reload_time < 0) )
2225 DEBUG( 3,( "Printcap cache time expired.\n"));
2226 reload_printers(msg_ctx);
2227 last_printer_reload_time = t;
2232 static bool fd_is_readable(int fd)
2234 fd_set fds;
2235 struct timeval timeout = {0, };
2236 int ret;
2238 FD_ZERO(&fds);
2239 FD_SET(fd, &fds);
2241 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2242 if (ret == -1) {
2243 return false;
2245 return FD_ISSET(fd, &fds);
2248 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2250 /* TODO: make write nonblocking */
2253 static void smbd_server_connection_read_handler(
2254 struct smbd_server_connection *conn, int fd)
2256 uint8_t *inbuf = NULL;
2257 size_t inbuf_len = 0;
2258 size_t unread_bytes = 0;
2259 bool encrypted = false;
2260 TALLOC_CTX *mem_ctx = talloc_tos();
2261 NTSTATUS status;
2262 uint32_t seqnum;
2264 bool from_client = (conn->sock == fd);
2266 if (from_client) {
2267 smbd_lock_socket(conn);
2269 if (!fd_is_readable(fd)) {
2270 DEBUG(10,("the echo listener was faster\n"));
2271 smbd_unlock_socket(conn);
2272 return;
2275 /* TODO: make this completely nonblocking */
2276 status = receive_smb_talloc(mem_ctx, fd,
2277 (char **)(void *)&inbuf,
2278 0, /* timeout */
2279 &unread_bytes,
2280 &encrypted,
2281 &inbuf_len, &seqnum,
2282 false /* trusted channel */);
2283 smbd_unlock_socket(conn);
2284 } else {
2285 /* TODO: make this completely nonblocking */
2286 status = receive_smb_talloc(mem_ctx, fd,
2287 (char **)(void *)&inbuf,
2288 0, /* timeout */
2289 &unread_bytes,
2290 &encrypted,
2291 &inbuf_len, &seqnum,
2292 true /* trusted channel */);
2295 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2296 goto process;
2298 if (NT_STATUS_IS_ERR(status)) {
2299 exit_server_cleanly("failed to receive smb request");
2301 if (!NT_STATUS_IS_OK(status)) {
2302 return;
2305 process:
2306 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2307 seqnum, encrypted, NULL);
2310 static void smbd_server_connection_handler(struct event_context *ev,
2311 struct fd_event *fde,
2312 uint16_t flags,
2313 void *private_data)
2315 struct smbd_server_connection *conn = talloc_get_type(private_data,
2316 struct smbd_server_connection);
2318 if (flags & EVENT_FD_WRITE) {
2319 smbd_server_connection_write_handler(conn);
2320 return;
2322 if (flags & EVENT_FD_READ) {
2323 smbd_server_connection_read_handler(conn, conn->sock);
2324 return;
2328 static void smbd_server_echo_handler(struct event_context *ev,
2329 struct fd_event *fde,
2330 uint16_t flags,
2331 void *private_data)
2333 struct smbd_server_connection *conn = talloc_get_type(private_data,
2334 struct smbd_server_connection);
2336 if (flags & EVENT_FD_WRITE) {
2337 smbd_server_connection_write_handler(conn);
2338 return;
2340 if (flags & EVENT_FD_READ) {
2341 smbd_server_connection_read_handler(
2342 conn, conn->smb1.echo_handler.trusted_fd);
2343 return;
2347 /****************************************************************************
2348 received when we should release a specific IP
2349 ****************************************************************************/
2350 static void release_ip(const char *ip, void *priv)
2352 char addr[INET6_ADDRSTRLEN];
2353 char *p = addr;
2355 client_socket_addr(smbd_server_fd(),addr,sizeof(addr));
2357 if (strncmp("::ffff:", addr, 7) == 0) {
2358 p = addr + 7;
2361 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2362 /* we can't afford to do a clean exit - that involves
2363 database writes, which would potentially mean we
2364 are still running after the failover has finished -
2365 we have to get rid of this process ID straight
2366 away */
2367 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2368 ip));
2369 /* note we must exit with non-zero status so the unclean handler gets
2370 called in the parent, so that the brl database is tickled */
2371 _exit(1);
2375 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2376 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2378 release_ip((char *)data->data, NULL);
2381 #ifdef CLUSTER_SUPPORT
2382 static int client_get_tcp_info(struct sockaddr_storage *server,
2383 struct sockaddr_storage *client)
2385 socklen_t length;
2386 if (server_fd == -1) {
2387 return -1;
2389 length = sizeof(*server);
2390 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2391 return -1;
2393 length = sizeof(*client);
2394 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2395 return -1;
2397 return 0;
2399 #endif
2402 * Send keepalive packets to our client
2404 static bool keepalive_fn(const struct timeval *now, void *private_data)
2406 struct smbd_server_connection *sconn = smbd_server_conn;
2407 bool ret;
2409 if (sconn->using_smb2) {
2410 /* Don't do keepalives on an SMB2 connection. */
2411 return false;
2414 smbd_lock_socket(smbd_server_conn);
2415 ret = send_keepalive(sconn->sock);
2416 smbd_unlock_socket(smbd_server_conn);
2418 if (!ret) {
2419 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2420 return False;
2422 return True;
2426 * Do the recurring check if we're idle
2428 static bool deadtime_fn(const struct timeval *now, void *private_data)
2430 struct smbd_server_connection *sconn =
2431 (struct smbd_server_connection *)private_data;
2433 if (sconn->using_smb2) {
2434 /* TODO: implement real idle check */
2435 if (sconn->smb2.sessions.list) {
2436 return true;
2438 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2439 messaging_send(sconn->msg_ctx, procid_self(),
2440 MSG_SHUTDOWN, &data_blob_null);
2441 return false;
2444 if ((conn_num_open(sconn) == 0)
2445 || (conn_idle_all(sconn, now->tv_sec))) {
2446 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2447 messaging_send(sconn->msg_ctx, procid_self(),
2448 MSG_SHUTDOWN, &data_blob_null);
2449 return False;
2452 return True;
2456 * Do the recurring log file and smb.conf reload checks.
2459 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2461 struct messaging_context *msg_ctx = talloc_get_type_abort(
2462 private_data, struct messaging_context);
2463 change_to_root_user();
2465 /* update printer queue caches if necessary */
2466 update_monitored_printq_cache(msg_ctx);
2468 /* check if we need to reload services */
2469 check_reload(msg_ctx, time(NULL));
2471 /* Change machine password if neccessary. */
2472 attempt_machine_password_change();
2475 * Force a log file check.
2477 force_check_log_size();
2478 check_log_size();
2479 return true;
2482 static int create_unlink_tmp(const char *dir)
2484 char *fname;
2485 int fd;
2487 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2488 if (fname == NULL) {
2489 errno = ENOMEM;
2490 return -1;
2492 fd = mkstemp(fname);
2493 if (fd == -1) {
2494 TALLOC_FREE(fname);
2495 return -1;
2497 if (unlink(fname) == -1) {
2498 int sys_errno = errno;
2499 close(fd);
2500 TALLOC_FREE(fname);
2501 errno = sys_errno;
2502 return -1;
2504 TALLOC_FREE(fname);
2505 return fd;
2508 struct smbd_echo_state {
2509 struct tevent_context *ev;
2510 struct iovec *pending;
2511 struct smbd_server_connection *sconn;
2512 int parent_pipe;
2514 struct tevent_fd *parent_fde;
2516 struct tevent_fd *read_fde;
2517 struct tevent_req *write_req;
2520 static void smbd_echo_writer_done(struct tevent_req *req);
2522 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2524 int num_pending;
2526 if (state->write_req != NULL) {
2527 return;
2530 num_pending = talloc_array_length(state->pending);
2531 if (num_pending == 0) {
2532 return;
2535 state->write_req = writev_send(state, state->ev, NULL,
2536 state->parent_pipe, false,
2537 state->pending, num_pending);
2538 if (state->write_req == NULL) {
2539 DEBUG(1, ("writev_send failed\n"));
2540 exit(1);
2543 talloc_steal(state->write_req, state->pending);
2544 state->pending = NULL;
2546 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2547 state);
2550 static void smbd_echo_writer_done(struct tevent_req *req)
2552 struct smbd_echo_state *state = tevent_req_callback_data(
2553 req, struct smbd_echo_state);
2554 ssize_t written;
2555 int err;
2557 written = writev_recv(req, &err);
2558 TALLOC_FREE(req);
2559 state->write_req = NULL;
2560 if (written == -1) {
2561 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2562 exit(1);
2564 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2565 smbd_echo_activate_writer(state);
2568 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2569 uint32_t seqnum)
2571 struct smb_request req;
2572 uint16_t num_replies;
2573 size_t out_len;
2574 char *outbuf;
2575 bool ok;
2577 if (inbuf_len < smb_size) {
2578 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2579 return false;
2581 if (!valid_smb_header(inbuf)) {
2582 DEBUG(10, ("Got invalid SMB header\n"));
2583 return false;
2586 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2587 seqnum)) {
2588 return false;
2590 req.inbuf = inbuf;
2592 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2593 smb_messages[req.cmd].name
2594 ? smb_messages[req.cmd].name : "unknown"));
2596 if (req.cmd != SMBecho) {
2597 return false;
2599 if (req.wct < 1) {
2600 return false;
2603 num_replies = SVAL(req.vwv+0, 0);
2604 if (num_replies != 1) {
2605 /* Not a Windows "Hey, you're still there?" request */
2606 return false;
2609 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2610 1, req.buflen)) {
2611 DEBUG(10, ("create_outbuf failed\n"));
2612 return false;
2614 req.outbuf = (uint8_t *)outbuf;
2616 SSVAL(req.outbuf, smb_vwv0, num_replies);
2618 if (req.buflen > 0) {
2619 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2622 out_len = smb_len(req.outbuf) + 4;
2624 ok = srv_send_smb(req.sconn->sock,
2625 (char *)outbuf,
2626 true, seqnum+1,
2627 false, &req.pcd);
2628 TALLOC_FREE(outbuf);
2629 if (!ok) {
2630 exit(1);
2633 return true;
2636 static void smbd_echo_exit(struct tevent_context *ev,
2637 struct tevent_fd *fde, uint16_t flags,
2638 void *private_data)
2640 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2641 exit(0);
2644 static void smbd_echo_reader(struct tevent_context *ev,
2645 struct tevent_fd *fde, uint16_t flags,
2646 void *private_data)
2648 struct smbd_echo_state *state = talloc_get_type_abort(
2649 private_data, struct smbd_echo_state);
2650 struct smbd_server_connection *sconn = state->sconn;
2651 size_t unread, num_pending;
2652 NTSTATUS status;
2653 struct iovec *tmp;
2654 uint32_t seqnum = 0;
2655 bool reply;
2656 bool ok;
2657 bool encrypted = false;
2659 smb_msleep(1000);
2661 ok = smbd_lock_socket_internal(sconn);
2662 if (!ok) {
2663 DEBUG(0, ("%s: failed to lock socket\n",
2664 __location__));
2665 exit(1);
2668 if (!fd_is_readable(sconn->sock)) {
2669 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2670 (int)sys_getpid()));
2671 ok = smbd_unlock_socket_internal(sconn);
2672 if (!ok) {
2673 DEBUG(1, ("%s: failed to unlock socket in\n",
2674 __location__));
2675 exit(1);
2677 return;
2680 num_pending = talloc_array_length(state->pending);
2681 tmp = talloc_realloc(state, state->pending, struct iovec,
2682 num_pending+1);
2683 if (tmp == NULL) {
2684 DEBUG(1, ("talloc_realloc failed\n"));
2685 exit(1);
2687 state->pending = tmp;
2689 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2691 status = receive_smb_talloc(state->pending, sconn->sock,
2692 (char **)(void *)&state->pending[num_pending].iov_base,
2693 0 /* timeout */,
2694 &unread,
2695 &encrypted,
2696 &state->pending[num_pending].iov_len,
2697 &seqnum,
2698 false /* trusted_channel*/);
2699 if (!NT_STATUS_IS_OK(status)) {
2700 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2701 (int)sys_getpid(), nt_errstr(status)));
2702 exit(1);
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);
2713 * place the seqnum in the packet so that the main process can reply
2714 * with signing
2716 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2717 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2719 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2720 state->pending[num_pending].iov_len,
2721 seqnum);
2722 if (reply) {
2723 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2724 /* no check, shrinking by some bytes does not fail */
2725 state->pending = talloc_realloc(state, state->pending,
2726 struct iovec,
2727 num_pending);
2728 } else {
2729 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2730 smbd_echo_activate_writer(state);
2734 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2735 int parent_pipe)
2737 struct smbd_echo_state *state;
2739 state = talloc_zero(sconn, struct smbd_echo_state);
2740 if (state == NULL) {
2741 DEBUG(1, ("talloc failed\n"));
2742 return;
2744 state->sconn = sconn;
2745 state->parent_pipe = parent_pipe;
2746 state->ev = s3_tevent_context_init(state);
2747 if (state->ev == NULL) {
2748 DEBUG(1, ("tevent_context_init failed\n"));
2749 TALLOC_FREE(state);
2750 return;
2752 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2753 TEVENT_FD_READ, smbd_echo_exit,
2754 state);
2755 if (state->parent_fde == NULL) {
2756 DEBUG(1, ("tevent_add_fd failed\n"));
2757 TALLOC_FREE(state);
2758 return;
2760 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2761 TEVENT_FD_READ, smbd_echo_reader,
2762 state);
2763 if (state->read_fde == NULL) {
2764 DEBUG(1, ("tevent_add_fd failed\n"));
2765 TALLOC_FREE(state);
2766 return;
2769 while (true) {
2770 if (tevent_loop_once(state->ev) == -1) {
2771 DEBUG(1, ("tevent_loop_once failed: %s\n",
2772 strerror(errno)));
2773 break;
2776 TALLOC_FREE(state);
2780 * Handle SMBecho requests in a forked child process
2782 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2784 int listener_pipe[2];
2785 int res;
2786 pid_t child;
2788 res = pipe(listener_pipe);
2789 if (res == -1) {
2790 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2791 return false;
2793 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2794 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2795 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2796 goto fail;
2799 child = sys_fork();
2800 if (child == 0) {
2801 NTSTATUS status;
2803 close(listener_pipe[0]);
2805 status = reinit_after_fork(sconn->msg_ctx,
2806 smbd_event_context(),
2807 procid_self(), false);
2808 if (!NT_STATUS_IS_OK(status)) {
2809 DEBUG(1, ("reinit_after_fork failed: %s\n",
2810 nt_errstr(status)));
2811 exit(1);
2813 smbd_echo_loop(sconn, listener_pipe[1]);
2814 exit(0);
2816 close(listener_pipe[1]);
2817 listener_pipe[1] = -1;
2818 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2820 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2823 * Without smb signing this is the same as the normal smbd
2824 * listener. This needs to change once signing comes in.
2826 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2827 sconn,
2828 sconn->smb1.echo_handler.trusted_fd,
2829 EVENT_FD_READ,
2830 smbd_server_echo_handler,
2831 sconn);
2832 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2833 DEBUG(1, ("event_add_fd failed\n"));
2834 goto fail;
2837 return true;
2839 fail:
2840 if (listener_pipe[0] != -1) {
2841 close(listener_pipe[0]);
2843 if (listener_pipe[1] != -1) {
2844 close(listener_pipe[1]);
2846 sconn->smb1.echo_handler.trusted_fd = -1;
2847 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2848 close(sconn->smb1.echo_handler.socket_lock_fd);
2850 sconn->smb1.echo_handler.trusted_fd = -1;
2851 sconn->smb1.echo_handler.socket_lock_fd = -1;
2852 return false;
2855 /****************************************************************************
2856 Process commands from the client
2857 ****************************************************************************/
2859 void smbd_process(struct smbd_server_connection *sconn)
2861 TALLOC_CTX *frame = talloc_stackframe();
2862 struct sockaddr_storage ss;
2863 struct sockaddr *sa = NULL;
2864 socklen_t sa_len;
2865 struct tsocket_address *local_address = NULL;
2866 struct tsocket_address *remote_address = NULL;
2867 const char *remaddr = NULL;
2868 int ret;
2870 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2871 lp_security() != SEC_SHARE &&
2872 !lp_async_smb_echo_handler()) {
2874 * We're not making the desion here,
2875 * we're just allowing the client
2876 * to decide between SMB1 and SMB2
2877 * with the first negprot
2878 * packet.
2880 sconn->using_smb2 = true;
2883 /* Ensure child is set to blocking mode */
2884 set_blocking(smbd_server_fd(),True);
2886 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2887 set_socket_options(smbd_server_fd(), lp_socket_options());
2889 sa = (struct sockaddr *)(void *)&ss;
2890 sa_len = sizeof(ss);
2891 ret = getpeername(smbd_server_fd(), sa, &sa_len);
2892 if (ret != 0) {
2893 int level = (errno == ENOTCONN)?2:0;
2894 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2895 exit_server_cleanly("getpeername() failed.\n");
2897 ret = tsocket_address_bsd_from_sockaddr(sconn,
2898 sa, sa_len,
2899 &remote_address);
2900 if (ret != 0) {
2901 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2902 __location__, strerror(errno)));
2903 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2906 sa = (struct sockaddr *)(void *)&ss;
2907 sa_len = sizeof(ss);
2908 ret = getsockname(smbd_server_fd(), sa, &sa_len);
2909 if (ret != 0) {
2910 int level = (errno == ENOTCONN)?2:0;
2911 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2912 exit_server_cleanly("getsockname() failed.\n");
2914 ret = tsocket_address_bsd_from_sockaddr(sconn,
2915 sa, sa_len,
2916 &local_address);
2917 if (ret != 0) {
2918 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2919 __location__, strerror(errno)));
2920 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2923 sconn->local_address = local_address;
2924 sconn->remote_address = remote_address;
2926 if (tsocket_address_is_inet(remote_address, "ip")) {
2927 remaddr = tsocket_address_inet_addr_string(
2928 sconn->remote_address,
2929 talloc_tos());
2930 if (remaddr == NULL) {
2933 } else {
2934 remaddr = "0.0.0.0";
2937 /* this is needed so that we get decent entries
2938 in smbstatus for port 445 connects */
2939 set_remote_machine_name(remaddr, false);
2940 reload_services(sconn->msg_ctx, true);
2943 * Before the first packet, check the global hosts allow/ hosts deny
2944 * parameters before doing any parsing of packets passed to us by the
2945 * client. This prevents attacks on our parsing code from hosts not in
2946 * the hosts allow list.
2949 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2950 lp_hostsdeny(-1))) {
2952 * send a negative session response "not listening on calling
2953 * name"
2955 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2956 DEBUG( 1, ("Connection denied from %s to %s\n",
2957 tsocket_address_string(remote_address, talloc_tos()),
2958 tsocket_address_string(local_address, talloc_tos())));
2959 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2960 0, false, NULL);
2961 exit_server_cleanly("connection denied");
2964 DEBUG(10, ("Connection allowed from %s to %s\n",
2965 tsocket_address_string(remote_address, talloc_tos()),
2966 tsocket_address_string(local_address, talloc_tos())));
2968 init_modules();
2970 smb_perfcount_init();
2972 if (!init_account_policy()) {
2973 exit_server("Could not open account policy tdb.\n");
2976 if (*lp_rootdir()) {
2977 if (chroot(lp_rootdir()) != 0) {
2978 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2979 exit_server("Failed to chroot()");
2981 if (chdir("/") == -1) {
2982 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2983 exit_server("Failed to chroot()");
2985 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2988 if (!srv_init_signing(sconn)) {
2989 exit_server("Failed to init smb_signing");
2992 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
2993 exit_server("Failed to fork echo handler");
2996 /* Setup oplocks */
2997 if (!init_oplocks(sconn->msg_ctx))
2998 exit_server("Failed to init oplocks");
3000 /* register our message handlers */
3001 messaging_register(sconn->msg_ctx, NULL,
3002 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3003 messaging_register(sconn->msg_ctx, NULL,
3004 MSG_SMB_RELEASE_IP, msg_release_ip);
3005 messaging_register(sconn->msg_ctx, NULL,
3006 MSG_SMB_CLOSE_FILE, msg_close_file);
3009 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3010 * MSGs to all child processes
3012 messaging_deregister(sconn->msg_ctx,
3013 MSG_DEBUG, NULL);
3014 messaging_register(sconn->msg_ctx, NULL,
3015 MSG_DEBUG, debug_message);
3017 if ((lp_keepalive() != 0)
3018 && !(event_add_idle(smbd_event_context(), NULL,
3019 timeval_set(lp_keepalive(), 0),
3020 "keepalive", keepalive_fn,
3021 NULL))) {
3022 DEBUG(0, ("Could not add keepalive event\n"));
3023 exit(1);
3026 if (!(event_add_idle(smbd_event_context(), NULL,
3027 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3028 "deadtime", deadtime_fn, sconn))) {
3029 DEBUG(0, ("Could not add deadtime event\n"));
3030 exit(1);
3033 if (!(event_add_idle(smbd_event_context(), NULL,
3034 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3035 "housekeeping", housekeeping_fn,
3036 sconn->msg_ctx))) {
3037 DEBUG(0, ("Could not add housekeeping event\n"));
3038 exit(1);
3041 #ifdef CLUSTER_SUPPORT
3043 if (lp_clustering()) {
3045 * We need to tell ctdb about our client's TCP
3046 * connection, so that for failover ctdbd can send
3047 * tickle acks, triggering a reconnection by the
3048 * client.
3051 struct sockaddr_storage srv, clnt;
3053 if (client_get_tcp_info(&srv, &clnt) == 0) {
3055 NTSTATUS status;
3057 status = ctdbd_register_ips(
3058 messaging_ctdbd_connection(procid_self()),
3059 &srv, &clnt, release_ip, NULL);
3061 if (!NT_STATUS_IS_OK(status)) {
3062 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3063 nt_errstr(status)));
3065 } else
3067 DEBUG(0,("Unable to get tcp info for "
3068 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3069 strerror(errno)));
3073 #endif
3075 sconn->nbt.got_session = false;
3077 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3079 sconn->smb1.sessions.done_sesssetup = false;
3080 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3081 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3082 /* users from session setup */
3083 sconn->smb1.sessions.session_userlist = NULL;
3084 /* workgroup from session setup. */
3085 sconn->smb1.sessions.session_workgroup = NULL;
3086 /* this holds info on user ids that are already validated for this VC */
3087 sconn->smb1.sessions.validated_users = NULL;
3088 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3089 sconn->smb1.sessions.num_validated_vuids = 0;
3091 conn_init(sconn);
3092 if (!init_dptrs(sconn)) {
3093 exit_server("init_dptrs() failed");
3096 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3097 sconn,
3098 smbd_server_fd(),
3099 EVENT_FD_READ,
3100 smbd_server_connection_handler,
3101 sconn);
3102 if (!sconn->smb1.fde) {
3103 exit_server("failed to create smbd_server_connection fde");
3106 TALLOC_FREE(frame);
3108 while (True) {
3109 NTSTATUS status;
3111 frame = talloc_stackframe_pool(8192);
3113 errno = 0;
3115 status = smbd_server_connection_loop_once(sconn);
3116 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3117 !NT_STATUS_IS_OK(status)) {
3118 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3119 " exiting\n", nt_errstr(status)));
3120 break;
3123 TALLOC_FREE(frame);
3126 exit_server_cleanly(NULL);
3129 bool req_is_in_chain(struct smb_request *req)
3131 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3133 * We're right now handling a subsequent request, so we must
3134 * be in a chain
3136 return true;
3139 if (!is_andx_req(req->cmd)) {
3140 return false;
3143 if (req->wct < 2) {
3145 * Okay, an illegal request, but definitely not chained :-)
3147 return false;
3150 return (CVAL(req->vwv+0, 0) != 0xFF);