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/>.
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,
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)
36 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
40 sconn->smb1.echo_handler.ref_count++;
42 if (sconn->smb1.echo_handler.ref_count > 1) {
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);
54 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
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)
70 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
74 sconn->smb1.echo_handler.ref_count--;
76 if (sconn->smb1.echo_handler.ref_count > 0) {
80 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
81 SMB_F_SETLKW, 0, 0, F_UNLCK);
86 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
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 /****************************************************************************
102 ****************************************************************************/
104 bool srv_send_smb(int fd, char *buffer,
105 bool do_signing, uint32_t seqnum,
107 struct smb_perfcount_data *pcd)
112 char *buf_out = buffer;
114 smbd_lock_socket(smbd_server_conn);
117 /* Sign the outgoing packet if required. */
118 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
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) ));
131 len = smb_len(buf_out) + 4;
133 ret = write_data(fd,buf_out+nwritten,len - nwritten);
136 char addr[INET6_ADDRSTRLEN];
138 * Try and give an error message saying what
141 DEBUG(0,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
142 (int)sys_getpid(), (int)len,
143 get_peer_addr(fd, addr, sizeof(addr)),
144 (int)ret, strerror(errno) ));
146 srv_free_enc_buffer(buf_out);
150 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
151 srv_free_enc_buffer(buf_out);
153 SMB_PERFCOUNT_END(pcd);
155 smbd_unlock_socket(smbd_server_conn);
159 /*******************************************************************
160 Setup the word count and byte count for a smb message.
161 ********************************************************************/
163 int srv_set_message(char *buf,
168 if (zero && (num_words || num_bytes)) {
169 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
171 SCVAL(buf,smb_wct,num_words);
172 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
173 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
174 return (smb_size + num_words*2 + num_bytes);
177 static bool valid_smb_header(const uint8_t *inbuf)
179 if (is_encrypted_packet(inbuf)) {
183 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
184 * but it just looks weird to call strncmp for this one.
186 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
189 /* Socket functions for smbd packet processing. */
191 static bool valid_packet_size(size_t len)
194 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
195 * of header. Don't print the error if this fits.... JRA.
198 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
199 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
200 (unsigned long)len));
206 static NTSTATUS read_packet_remainder(int fd, char *buffer,
207 unsigned int timeout, ssize_t len)
213 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
216 /****************************************************************************
217 Attempt a zerocopy writeX read. We know here that len > smb_size-4
218 ****************************************************************************/
221 * Unfortunately, earlier versions of smbclient/libsmbclient
222 * don't send this "standard" writeX header. I've fixed this
223 * for 3.2 but we'll use the old method with earlier versions.
224 * Windows and CIFSFS at least use this standard size. Not
228 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
229 (2*14) + /* word count (including bcc) */ \
232 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
233 const char lenbuf[4],
234 int fd, char **buffer,
235 unsigned int timeout,
239 /* Size of a WRITEX call (+4 byte len). */
240 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
241 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
245 memcpy(writeX_header, lenbuf, 4);
247 status = read_fd_with_timeout(
248 fd, writeX_header + 4,
249 STANDARD_WRITE_AND_X_HEADER_SIZE,
250 STANDARD_WRITE_AND_X_HEADER_SIZE,
253 if (!NT_STATUS_IS_OK(status)) {
258 * Ok - now try and see if this is a possible
262 if (is_valid_writeX_buffer(smbd_server_conn,
263 (uint8_t *)writeX_header)) {
265 * If the data offset is beyond what
266 * we've read, drain the extra bytes.
268 uint16_t doff = SVAL(writeX_header,smb_vwv11);
271 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
272 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
273 if (drain_socket(fd, drain) != drain) {
274 smb_panic("receive_smb_raw_talloc_partial_read:"
275 " failed to drain pending bytes");
278 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
281 /* Spoof down the length and null out the bcc. */
282 set_message_bcc(writeX_header, 0);
283 newlen = smb_len(writeX_header);
285 /* Copy the header we've written. */
287 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
289 sizeof(writeX_header));
291 if (*buffer == NULL) {
292 DEBUG(0, ("Could not allocate inbuf of length %d\n",
293 (int)sizeof(writeX_header)));
294 return NT_STATUS_NO_MEMORY;
297 /* Work out the remaining bytes. */
298 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
299 *len_ret = newlen + 4;
303 if (!valid_packet_size(len)) {
304 return NT_STATUS_INVALID_PARAMETER;
308 * Not a valid writeX call. Just do the standard
312 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
314 if (*buffer == NULL) {
315 DEBUG(0, ("Could not allocate inbuf of length %d\n",
317 return NT_STATUS_NO_MEMORY;
320 /* Copy in what we already read. */
323 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
324 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
327 status = read_packet_remainder(
328 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
331 if (!NT_STATUS_IS_OK(status)) {
332 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
342 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
343 char **buffer, unsigned int timeout,
344 size_t *p_unread, size_t *plen)
348 int min_recv_size = lp_min_receive_file_size();
353 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
354 if (!NT_STATUS_IS_OK(status)) {
355 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
359 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
360 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
361 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
362 !srv_is_signing_active(smbd_server_conn) &&
363 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
365 return receive_smb_raw_talloc_partial_read(
366 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
369 if (!valid_packet_size(len)) {
370 return NT_STATUS_INVALID_PARAMETER;
374 * The +4 here can't wrap, we've checked the length above already.
377 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
379 if (*buffer == NULL) {
380 DEBUG(0, ("Could not allocate inbuf of length %d\n",
382 return NT_STATUS_NO_MEMORY;
385 memcpy(*buffer, lenbuf, sizeof(lenbuf));
387 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
388 if (!NT_STATUS_IS_OK(status)) {
396 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
397 char **buffer, unsigned int timeout,
398 size_t *p_unread, bool *p_encrypted,
401 bool trusted_channel)
406 *p_encrypted = false;
408 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
410 if (!NT_STATUS_IS_OK(status)) {
414 if (is_encrypted_packet((uint8_t *)*buffer)) {
415 status = srv_decrypt_buffer(*buffer);
416 if (!NT_STATUS_IS_OK(status)) {
417 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
418 "incoming packet! Error %s\n",
419 nt_errstr(status) ));
425 /* Check the incoming SMB signature. */
426 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
427 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
428 "incoming packet!\n"));
429 return NT_STATUS_INVALID_NETWORK_RESPONSE;
437 * Initialize a struct smb_request from an inbuf
440 static bool init_smb_request(struct smb_request *req,
441 struct smbd_server_connection *sconn,
443 size_t unread_bytes, bool encrypted,
446 size_t req_size = smb_len(inbuf) + 4;
447 /* Ensure we have at least smb_size bytes. */
448 if (req_size < smb_size) {
449 DEBUG(0,("init_smb_request: invalid request size %u\n",
450 (unsigned int)req_size ));
453 req->cmd = CVAL(inbuf, smb_com);
454 req->flags2 = SVAL(inbuf, smb_flg2);
455 req->smbpid = SVAL(inbuf, smb_pid);
456 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
457 req->seqnum = seqnum;
458 req->vuid = SVAL(inbuf, smb_uid);
459 req->tid = SVAL(inbuf, smb_tid);
460 req->wct = CVAL(inbuf, smb_wct);
461 req->vwv = (uint16_t *)(inbuf+smb_vwv);
462 req->buflen = smb_buflen(inbuf);
463 req->buf = (const uint8_t *)smb_buf(inbuf);
464 req->unread_bytes = unread_bytes;
465 req->encrypted = encrypted;
467 req->conn = conn_find(sconn,req->tid);
468 req->chain_fsp = NULL;
469 req->chain_outbuf = NULL;
472 smb_init_perfcount_data(&req->pcd);
474 /* Ensure we have at least wct words and 2 bytes of bcc. */
475 if (smb_size + req->wct*2 > req_size) {
476 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
477 (unsigned int)req->wct,
478 (unsigned int)req_size));
481 /* Ensure bcc is correct. */
482 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
483 DEBUG(0,("init_smb_request: invalid bcc number %u "
484 "(wct = %u, size %u)\n",
485 (unsigned int)req->buflen,
486 (unsigned int)req->wct,
487 (unsigned int)req_size));
495 static void process_smb(struct smbd_server_connection *conn,
496 uint8_t *inbuf, size_t nread, size_t unread_bytes,
497 uint32_t seqnum, bool encrypted,
498 struct smb_perfcount_data *deferred_pcd);
500 static void smbd_deferred_open_timer(struct event_context *ev,
501 struct timed_event *te,
502 struct timeval _tval,
505 struct pending_message_list *msg = talloc_get_type(private_data,
506 struct pending_message_list);
507 TALLOC_CTX *mem_ctx = talloc_tos();
508 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
511 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
514 exit_server("smbd_deferred_open_timer: talloc failed\n");
518 /* We leave this message on the queue so the open code can
519 know this is a retry. */
520 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
521 (unsigned long long)mid ));
523 /* Mark the message as processed so this is not
524 * re-processed in error. */
525 msg->processed = true;
527 process_smb(smbd_server_conn, inbuf,
529 msg->seqnum, msg->encrypted, &msg->pcd);
531 /* If it's still there and was processed, remove it. */
532 msg = get_deferred_open_message_smb(mid);
533 if (msg && msg->processed) {
534 remove_deferred_open_message_smb(mid);
538 /****************************************************************************
539 Function to push a message onto the tail of a linked list of smb messages ready
541 ****************************************************************************/
543 static bool push_queued_message(struct smb_request *req,
544 struct timeval request_time,
545 struct timeval end_time,
546 char *private_data, size_t private_len)
548 int msg_len = smb_len(req->inbuf) + 4;
549 struct pending_message_list *msg;
551 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
554 DEBUG(0,("push_message: malloc fail (1)\n"));
558 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
559 if(msg->buf.data == NULL) {
560 DEBUG(0,("push_message: malloc fail (2)\n"));
565 msg->request_time = request_time;
566 msg->seqnum = req->seqnum;
567 msg->encrypted = req->encrypted;
568 msg->processed = false;
569 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
572 msg->private_data = data_blob_talloc(msg, private_data,
574 if (msg->private_data.data == NULL) {
575 DEBUG(0,("push_message: malloc fail (3)\n"));
581 msg->te = event_add_timed(smbd_event_context(),
584 smbd_deferred_open_timer,
587 DEBUG(0,("push_message: event_add_timed failed\n"));
592 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
594 DEBUG(10,("push_message: pushed message length %u on "
595 "deferred_open_queue\n", (unsigned int)msg_len));
600 /****************************************************************************
601 Function to delete a sharing violation open message by mid.
602 ****************************************************************************/
604 void remove_deferred_open_message_smb(uint64_t mid)
606 struct pending_message_list *pml;
608 if (smbd_server_conn->using_smb2) {
609 remove_deferred_open_message_smb2(smbd_server_conn, mid);
613 for (pml = deferred_open_queue; pml; pml = pml->next) {
614 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
615 DEBUG(10,("remove_deferred_open_message_smb: "
616 "deleting mid %llu len %u\n",
617 (unsigned long long)mid,
618 (unsigned int)pml->buf.length ));
619 DLIST_REMOVE(deferred_open_queue, pml);
626 /****************************************************************************
627 Move a sharing violation open retry message to the front of the list and
628 schedule it for immediate processing.
629 ****************************************************************************/
631 void schedule_deferred_open_message_smb(uint64_t mid)
633 struct pending_message_list *pml;
636 if (smbd_server_conn->using_smb2) {
637 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
641 for (pml = deferred_open_queue; pml; pml = pml->next) {
642 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
644 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
647 (unsigned long long)msg_mid ));
649 if (mid == msg_mid) {
650 struct timed_event *te;
652 if (pml->processed) {
653 /* A processed message should not be
655 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
656 "message mid %llu was already processed\n",
657 (unsigned long long)msg_mid ));
661 DEBUG(10,("schedule_deferred_open_message_smb: "
662 "scheduling mid %llu\n",
663 (unsigned long long)mid ));
665 te = event_add_timed(smbd_event_context(),
668 smbd_deferred_open_timer,
671 DEBUG(10,("schedule_deferred_open_message_smb: "
672 "event_add_timed() failed, "
673 "skipping mid %llu\n",
674 (unsigned long long)msg_mid ));
677 TALLOC_FREE(pml->te);
679 DLIST_PROMOTE(deferred_open_queue, pml);
684 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
685 "find message mid %llu\n",
686 (unsigned long long)mid ));
689 /****************************************************************************
690 Return true if this mid is on the deferred queue and was not yet processed.
691 ****************************************************************************/
693 bool open_was_deferred(uint64_t mid)
695 struct pending_message_list *pml;
697 if (smbd_server_conn->using_smb2) {
698 return open_was_deferred_smb2(smbd_server_conn, mid);
701 for (pml = deferred_open_queue; pml; pml = pml->next) {
702 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
709 /****************************************************************************
710 Return the message queued by this mid.
711 ****************************************************************************/
713 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
715 struct pending_message_list *pml;
717 for (pml = deferred_open_queue; pml; pml = pml->next) {
718 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
725 /****************************************************************************
726 Get the state data queued by this mid.
727 ****************************************************************************/
729 bool get_deferred_open_message_state(struct smb_request *smbreq,
730 struct timeval *p_request_time,
733 struct pending_message_list *pml;
735 if (smbd_server_conn->using_smb2) {
736 return get_deferred_open_message_state_smb2(smbreq->smb2req,
741 pml = get_deferred_open_message_smb(smbreq->mid);
745 if (p_request_time) {
746 *p_request_time = pml->request_time;
749 *pp_state = (void *)pml->private_data.data;
754 /****************************************************************************
755 Function to push a deferred open smb message onto a linked list of local smb
756 messages ready for processing.
757 ****************************************************************************/
759 bool push_deferred_open_message_smb(struct smb_request *req,
760 struct timeval request_time,
761 struct timeval timeout,
763 char *private_data, size_t priv_len)
765 struct timeval end_time;
768 return push_deferred_open_message_smb2(req->smb2req,
776 if (req->unread_bytes) {
777 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
778 "unread_bytes = %u\n",
779 (unsigned int)req->unread_bytes ));
780 smb_panic("push_deferred_open_message_smb: "
781 "logic error unread_bytes != 0" );
784 end_time = timeval_sum(&request_time, &timeout);
786 DEBUG(10,("push_deferred_open_message_smb: pushing message "
787 "len %u mid %llu timeout time [%u.%06u]\n",
788 (unsigned int) smb_len(req->inbuf)+4,
789 (unsigned long long)req->mid,
790 (unsigned int)end_time.tv_sec,
791 (unsigned int)end_time.tv_usec));
793 return push_queued_message(req, request_time, end_time,
794 private_data, priv_len);
798 struct timed_event *te;
799 struct timeval interval;
801 bool (*handler)(const struct timeval *now, void *private_data);
805 static void smbd_idle_event_handler(struct event_context *ctx,
806 struct timed_event *te,
810 struct idle_event *event =
811 talloc_get_type_abort(private_data, struct idle_event);
813 TALLOC_FREE(event->te);
815 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
816 event->name, event->te));
818 if (!event->handler(&now, event->private_data)) {
819 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
820 event->name, event->te));
821 /* Don't repeat, delete ourselves */
826 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
827 event->name, event->te));
829 event->te = event_add_timed(ctx, event,
830 timeval_sum(&now, &event->interval),
831 smbd_idle_event_handler, event);
833 /* We can't do much but fail here. */
834 SMB_ASSERT(event->te != NULL);
837 struct idle_event *event_add_idle(struct event_context *event_ctx,
839 struct timeval interval,
841 bool (*handler)(const struct timeval *now,
845 struct idle_event *result;
846 struct timeval now = timeval_current();
848 result = TALLOC_P(mem_ctx, struct idle_event);
849 if (result == NULL) {
850 DEBUG(0, ("talloc failed\n"));
854 result->interval = interval;
855 result->handler = handler;
856 result->private_data = private_data;
858 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
859 DEBUG(0, ("talloc failed\n"));
864 result->te = event_add_timed(event_ctx, result,
865 timeval_sum(&now, &interval),
866 smbd_idle_event_handler, result);
867 if (result->te == NULL) {
868 DEBUG(0, ("event_add_timed failed\n"));
873 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
877 static void smbd_sig_term_handler(struct tevent_context *ev,
878 struct tevent_signal *se,
884 exit_server_cleanly("termination signal");
887 void smbd_setup_sig_term_handler(void)
889 struct tevent_signal *se;
891 se = tevent_add_signal(smbd_event_context(),
892 smbd_event_context(),
894 smbd_sig_term_handler,
897 exit_server("failed to setup SIGTERM handler");
901 static void smbd_sig_hup_handler(struct tevent_context *ev,
902 struct tevent_signal *se,
908 struct messaging_context *msg_ctx = talloc_get_type_abort(
909 private_data, struct messaging_context);
910 change_to_root_user();
911 DEBUG(1,("Reloading services after SIGHUP\n"));
912 reload_services(msg_ctx, False);
915 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
916 struct messaging_context *msg_ctx)
918 struct tevent_signal *se;
920 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
923 exit_server("failed to setup SIGHUP handler");
927 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
934 to.tv_sec = SMBD_SELECT_TIMEOUT;
938 * Setup the select fd sets.
945 * Are there any timed events waiting ? If so, ensure we don't
946 * select for longer than it would take to wait for them.
953 event_add_to_select_args(smbd_event_context(), &now,
954 &r_fds, &w_fds, &to, &maxfd);
957 /* Process a signal and timed events now... */
958 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
959 return NT_STATUS_RETRY;
964 START_PROFILE(smbd_idle);
966 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
969 END_PROFILE(smbd_idle);
973 if ((conn->smb1.echo_handler.trusted_fd != -1)
974 && FD_ISSET(conn->sock, &r_fds)
975 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
977 * Prefer to read pending requests from the echo handler. To
978 * quote Jeremy (da70f8ab1): This is a hack of monstrous
981 FD_CLR(conn->sock, &r_fds);
984 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
985 return NT_STATUS_RETRY;
990 /* something is wrong. Maybe the socket is dead? */
991 return map_nt_error_from_unix(errno);
994 /* Did we timeout ? */
996 return NT_STATUS_RETRY;
999 /* should not be reached */
1000 return NT_STATUS_INTERNAL_ERROR;
1004 * Only allow 5 outstanding trans requests. We're allocating memory, so
1008 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1011 for (; list != NULL; list = list->next) {
1013 if (list->mid == mid) {
1014 return NT_STATUS_INVALID_PARAMETER;
1020 return NT_STATUS_INSUFFICIENT_RESOURCES;
1023 return NT_STATUS_OK;
1027 These flags determine some of the permissions required to do an operation
1029 Note that I don't set NEED_WRITE on some write operations because they
1030 are used by some brain-dead clients when printing, and I don't want to
1031 force write permissions on print services.
1033 #define AS_USER (1<<0)
1034 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1035 #define TIME_INIT (1<<2)
1036 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1037 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1038 #define DO_CHDIR (1<<6)
1041 define a list of possible SMB messages and their corresponding
1042 functions. Any message that has a NULL function is unimplemented -
1043 please feel free to contribute implementations!
1045 static const struct smb_message_struct {
1047 void (*fn)(struct smb_request *req);
1049 } smb_messages[256] = {
1051 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1052 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1053 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1054 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1055 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1056 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1057 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1058 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1059 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1060 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1061 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1062 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1063 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1064 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1065 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1066 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1067 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1068 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1069 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1070 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1071 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1072 /* 0x15 */ { NULL, NULL, 0 },
1073 /* 0x16 */ { NULL, NULL, 0 },
1074 /* 0x17 */ { NULL, NULL, 0 },
1075 /* 0x18 */ { NULL, NULL, 0 },
1076 /* 0x19 */ { NULL, NULL, 0 },
1077 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1078 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1079 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1080 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1081 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1082 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1083 /* 0x20 */ { "SMBwritec", NULL,0},
1084 /* 0x21 */ { NULL, NULL, 0 },
1085 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1086 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1087 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1088 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1089 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1090 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1091 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1092 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1093 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1094 /* 0x2b */ { "SMBecho",reply_echo,0},
1095 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1096 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1097 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1098 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1099 /* 0x30 */ { NULL, NULL, 0 },
1100 /* 0x31 */ { NULL, NULL, 0 },
1101 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1102 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1103 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1104 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1105 /* 0x36 */ { NULL, NULL, 0 },
1106 /* 0x37 */ { NULL, NULL, 0 },
1107 /* 0x38 */ { NULL, NULL, 0 },
1108 /* 0x39 */ { NULL, NULL, 0 },
1109 /* 0x3a */ { NULL, NULL, 0 },
1110 /* 0x3b */ { NULL, NULL, 0 },
1111 /* 0x3c */ { NULL, NULL, 0 },
1112 /* 0x3d */ { NULL, NULL, 0 },
1113 /* 0x3e */ { NULL, NULL, 0 },
1114 /* 0x3f */ { NULL, NULL, 0 },
1115 /* 0x40 */ { NULL, NULL, 0 },
1116 /* 0x41 */ { NULL, NULL, 0 },
1117 /* 0x42 */ { NULL, NULL, 0 },
1118 /* 0x43 */ { NULL, NULL, 0 },
1119 /* 0x44 */ { NULL, NULL, 0 },
1120 /* 0x45 */ { NULL, NULL, 0 },
1121 /* 0x46 */ { NULL, NULL, 0 },
1122 /* 0x47 */ { NULL, NULL, 0 },
1123 /* 0x48 */ { NULL, NULL, 0 },
1124 /* 0x49 */ { NULL, NULL, 0 },
1125 /* 0x4a */ { NULL, NULL, 0 },
1126 /* 0x4b */ { NULL, NULL, 0 },
1127 /* 0x4c */ { NULL, NULL, 0 },
1128 /* 0x4d */ { NULL, NULL, 0 },
1129 /* 0x4e */ { NULL, NULL, 0 },
1130 /* 0x4f */ { NULL, NULL, 0 },
1131 /* 0x50 */ { NULL, NULL, 0 },
1132 /* 0x51 */ { NULL, NULL, 0 },
1133 /* 0x52 */ { NULL, NULL, 0 },
1134 /* 0x53 */ { NULL, NULL, 0 },
1135 /* 0x54 */ { NULL, NULL, 0 },
1136 /* 0x55 */ { NULL, NULL, 0 },
1137 /* 0x56 */ { NULL, NULL, 0 },
1138 /* 0x57 */ { NULL, NULL, 0 },
1139 /* 0x58 */ { NULL, NULL, 0 },
1140 /* 0x59 */ { NULL, NULL, 0 },
1141 /* 0x5a */ { NULL, NULL, 0 },
1142 /* 0x5b */ { NULL, NULL, 0 },
1143 /* 0x5c */ { NULL, NULL, 0 },
1144 /* 0x5d */ { NULL, NULL, 0 },
1145 /* 0x5e */ { NULL, NULL, 0 },
1146 /* 0x5f */ { NULL, NULL, 0 },
1147 /* 0x60 */ { NULL, NULL, 0 },
1148 /* 0x61 */ { NULL, NULL, 0 },
1149 /* 0x62 */ { NULL, NULL, 0 },
1150 /* 0x63 */ { NULL, NULL, 0 },
1151 /* 0x64 */ { NULL, NULL, 0 },
1152 /* 0x65 */ { NULL, NULL, 0 },
1153 /* 0x66 */ { NULL, NULL, 0 },
1154 /* 0x67 */ { NULL, NULL, 0 },
1155 /* 0x68 */ { NULL, NULL, 0 },
1156 /* 0x69 */ { NULL, NULL, 0 },
1157 /* 0x6a */ { NULL, NULL, 0 },
1158 /* 0x6b */ { NULL, NULL, 0 },
1159 /* 0x6c */ { NULL, NULL, 0 },
1160 /* 0x6d */ { NULL, NULL, 0 },
1161 /* 0x6e */ { NULL, NULL, 0 },
1162 /* 0x6f */ { NULL, NULL, 0 },
1163 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1164 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1165 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1166 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1167 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1168 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1169 /* 0x76 */ { NULL, NULL, 0 },
1170 /* 0x77 */ { NULL, NULL, 0 },
1171 /* 0x78 */ { NULL, NULL, 0 },
1172 /* 0x79 */ { NULL, NULL, 0 },
1173 /* 0x7a */ { NULL, NULL, 0 },
1174 /* 0x7b */ { NULL, NULL, 0 },
1175 /* 0x7c */ { NULL, NULL, 0 },
1176 /* 0x7d */ { NULL, NULL, 0 },
1177 /* 0x7e */ { NULL, NULL, 0 },
1178 /* 0x7f */ { NULL, NULL, 0 },
1179 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1180 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1181 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1182 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1183 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1184 /* 0x85 */ { NULL, NULL, 0 },
1185 /* 0x86 */ { NULL, NULL, 0 },
1186 /* 0x87 */ { NULL, NULL, 0 },
1187 /* 0x88 */ { NULL, NULL, 0 },
1188 /* 0x89 */ { NULL, NULL, 0 },
1189 /* 0x8a */ { NULL, NULL, 0 },
1190 /* 0x8b */ { NULL, NULL, 0 },
1191 /* 0x8c */ { NULL, NULL, 0 },
1192 /* 0x8d */ { NULL, NULL, 0 },
1193 /* 0x8e */ { NULL, NULL, 0 },
1194 /* 0x8f */ { NULL, NULL, 0 },
1195 /* 0x90 */ { NULL, NULL, 0 },
1196 /* 0x91 */ { NULL, NULL, 0 },
1197 /* 0x92 */ { NULL, NULL, 0 },
1198 /* 0x93 */ { NULL, NULL, 0 },
1199 /* 0x94 */ { NULL, NULL, 0 },
1200 /* 0x95 */ { NULL, NULL, 0 },
1201 /* 0x96 */ { NULL, NULL, 0 },
1202 /* 0x97 */ { NULL, NULL, 0 },
1203 /* 0x98 */ { NULL, NULL, 0 },
1204 /* 0x99 */ { NULL, NULL, 0 },
1205 /* 0x9a */ { NULL, NULL, 0 },
1206 /* 0x9b */ { NULL, NULL, 0 },
1207 /* 0x9c */ { NULL, NULL, 0 },
1208 /* 0x9d */ { NULL, NULL, 0 },
1209 /* 0x9e */ { NULL, NULL, 0 },
1210 /* 0x9f */ { NULL, NULL, 0 },
1211 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1212 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1213 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1214 /* 0xa3 */ { NULL, NULL, 0 },
1215 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1216 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1217 /* 0xa6 */ { NULL, NULL, 0 },
1218 /* 0xa7 */ { NULL, NULL, 0 },
1219 /* 0xa8 */ { NULL, NULL, 0 },
1220 /* 0xa9 */ { NULL, NULL, 0 },
1221 /* 0xaa */ { NULL, NULL, 0 },
1222 /* 0xab */ { NULL, NULL, 0 },
1223 /* 0xac */ { NULL, NULL, 0 },
1224 /* 0xad */ { NULL, NULL, 0 },
1225 /* 0xae */ { NULL, NULL, 0 },
1226 /* 0xaf */ { NULL, NULL, 0 },
1227 /* 0xb0 */ { NULL, NULL, 0 },
1228 /* 0xb1 */ { NULL, NULL, 0 },
1229 /* 0xb2 */ { NULL, NULL, 0 },
1230 /* 0xb3 */ { NULL, NULL, 0 },
1231 /* 0xb4 */ { NULL, NULL, 0 },
1232 /* 0xb5 */ { NULL, NULL, 0 },
1233 /* 0xb6 */ { NULL, NULL, 0 },
1234 /* 0xb7 */ { NULL, NULL, 0 },
1235 /* 0xb8 */ { NULL, NULL, 0 },
1236 /* 0xb9 */ { NULL, NULL, 0 },
1237 /* 0xba */ { NULL, NULL, 0 },
1238 /* 0xbb */ { NULL, NULL, 0 },
1239 /* 0xbc */ { NULL, NULL, 0 },
1240 /* 0xbd */ { NULL, NULL, 0 },
1241 /* 0xbe */ { NULL, NULL, 0 },
1242 /* 0xbf */ { NULL, NULL, 0 },
1243 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1244 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1245 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1246 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1247 /* 0xc4 */ { NULL, NULL, 0 },
1248 /* 0xc5 */ { NULL, NULL, 0 },
1249 /* 0xc6 */ { NULL, NULL, 0 },
1250 /* 0xc7 */ { NULL, NULL, 0 },
1251 /* 0xc8 */ { NULL, NULL, 0 },
1252 /* 0xc9 */ { NULL, NULL, 0 },
1253 /* 0xca */ { NULL, NULL, 0 },
1254 /* 0xcb */ { NULL, NULL, 0 },
1255 /* 0xcc */ { NULL, NULL, 0 },
1256 /* 0xcd */ { NULL, NULL, 0 },
1257 /* 0xce */ { NULL, NULL, 0 },
1258 /* 0xcf */ { NULL, NULL, 0 },
1259 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1260 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1261 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1262 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1263 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1264 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1265 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1266 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1267 /* 0xd8 */ { NULL, NULL, 0 },
1268 /* 0xd9 */ { NULL, NULL, 0 },
1269 /* 0xda */ { NULL, NULL, 0 },
1270 /* 0xdb */ { NULL, NULL, 0 },
1271 /* 0xdc */ { NULL, NULL, 0 },
1272 /* 0xdd */ { NULL, NULL, 0 },
1273 /* 0xde */ { NULL, NULL, 0 },
1274 /* 0xdf */ { NULL, NULL, 0 },
1275 /* 0xe0 */ { NULL, NULL, 0 },
1276 /* 0xe1 */ { NULL, NULL, 0 },
1277 /* 0xe2 */ { NULL, NULL, 0 },
1278 /* 0xe3 */ { NULL, NULL, 0 },
1279 /* 0xe4 */ { NULL, NULL, 0 },
1280 /* 0xe5 */ { NULL, NULL, 0 },
1281 /* 0xe6 */ { NULL, NULL, 0 },
1282 /* 0xe7 */ { NULL, NULL, 0 },
1283 /* 0xe8 */ { NULL, NULL, 0 },
1284 /* 0xe9 */ { NULL, NULL, 0 },
1285 /* 0xea */ { NULL, NULL, 0 },
1286 /* 0xeb */ { NULL, NULL, 0 },
1287 /* 0xec */ { NULL, NULL, 0 },
1288 /* 0xed */ { NULL, NULL, 0 },
1289 /* 0xee */ { NULL, NULL, 0 },
1290 /* 0xef */ { NULL, NULL, 0 },
1291 /* 0xf0 */ { NULL, NULL, 0 },
1292 /* 0xf1 */ { NULL, NULL, 0 },
1293 /* 0xf2 */ { NULL, NULL, 0 },
1294 /* 0xf3 */ { NULL, NULL, 0 },
1295 /* 0xf4 */ { NULL, NULL, 0 },
1296 /* 0xf5 */ { NULL, NULL, 0 },
1297 /* 0xf6 */ { NULL, NULL, 0 },
1298 /* 0xf7 */ { NULL, NULL, 0 },
1299 /* 0xf8 */ { NULL, NULL, 0 },
1300 /* 0xf9 */ { NULL, NULL, 0 },
1301 /* 0xfa */ { NULL, NULL, 0 },
1302 /* 0xfb */ { NULL, NULL, 0 },
1303 /* 0xfc */ { NULL, NULL, 0 },
1304 /* 0xfd */ { NULL, NULL, 0 },
1305 /* 0xfe */ { NULL, NULL, 0 },
1306 /* 0xff */ { NULL, NULL, 0 }
1310 /*******************************************************************
1311 allocate and initialize a reply packet
1312 ********************************************************************/
1314 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1315 const char *inbuf, char **outbuf, uint8_t num_words,
1319 * Protect against integer wrap
1321 if ((num_bytes > 0xffffff)
1322 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1324 if (asprintf(&msg, "num_bytes too large: %u",
1325 (unsigned)num_bytes) == -1) {
1326 msg = CONST_DISCARD(char *, "num_bytes too large");
1331 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1332 smb_size + num_words*2 + num_bytes);
1333 if (*outbuf == NULL) {
1337 construct_reply_common(req, inbuf, *outbuf);
1338 srv_set_message(*outbuf, num_words, num_bytes, false);
1340 * Zero out the word area, the caller has to take care of the bcc area
1343 if (num_words != 0) {
1344 memset(*outbuf + smb_vwv0, 0, num_words*2);
1350 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1353 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1355 smb_panic("could not allocate output buffer\n");
1357 req->outbuf = (uint8_t *)outbuf;
1361 /*******************************************************************
1362 Dump a packet to a file.
1363 ********************************************************************/
1365 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1369 if (DEBUGLEVEL < 50) {
1373 if (len < 4) len = smb_len(data)+4;
1374 for (i=1;i<100;i++) {
1375 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1376 type ? "req" : "resp") == -1) {
1379 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1380 if (fd != -1 || errno != EEXIST) break;
1383 ssize_t ret = write(fd, data, len);
1385 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1387 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1392 /****************************************************************************
1393 Prepare everything for calling the actual request function, and potentially
1394 call the request function via the "new" interface.
1396 Return False if the "legacy" function needs to be called, everything is
1399 Return True if we're done.
1401 I know this API sucks, but it is the one with the least code change I could
1403 ****************************************************************************/
1405 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1409 connection_struct *conn = NULL;
1410 struct smbd_server_connection *sconn = req->sconn;
1414 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1415 * so subtract 4 from it. */
1416 if (!valid_smb_header(req->inbuf)
1417 || (size < (smb_size - 4))) {
1418 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1419 smb_len(req->inbuf)));
1420 exit_server_cleanly("Non-SMB packet");
1423 if (smb_messages[type].fn == NULL) {
1424 DEBUG(0,("Unknown message type %d!\n",type));
1425 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1426 reply_unknown_new(req, type);
1430 flags = smb_messages[type].flags;
1432 /* In share mode security we must ignore the vuid. */
1433 session_tag = (lp_security() == SEC_SHARE)
1434 ? UID_FIELD_INVALID : req->vuid;
1437 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1438 (int)sys_getpid(), (unsigned long)conn));
1440 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1442 /* Ensure this value is replaced in the incoming packet. */
1443 SSVAL(req->inbuf,smb_uid,session_tag);
1446 * Ensure the correct username is in current_user_info. This is a
1447 * really ugly bugfix for problems with multiple session_setup_and_X's
1448 * being done and allowing %U and %G substitutions to work correctly.
1449 * There is a reason this code is done here, don't move it unless you
1450 * know what you're doing... :-).
1454 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1455 user_struct *vuser = NULL;
1457 sconn->smb1.sessions.last_session_tag = session_tag;
1458 if(session_tag != UID_FIELD_INVALID) {
1459 vuser = get_valid_user_struct(sconn, session_tag);
1461 set_current_user_info(
1462 vuser->server_info->sanitized_username,
1463 vuser->server_info->unix_name,
1464 vuser->server_info->info3->base.domain.string);
1469 /* Does this call need to be run as the connected user? */
1470 if (flags & AS_USER) {
1472 /* Does this call need a valid tree connection? */
1475 * Amazingly, the error code depends on the command
1478 if (type == SMBntcreateX) {
1479 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1481 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1486 if (!change_to_user(conn,session_tag)) {
1487 DEBUG(0, ("Error: Could not change to user. Removing "
1488 "deferred open, mid=%llu.\n",
1489 (unsigned long long)req->mid));
1490 reply_force_doserror(req, ERRSRV, ERRbaduid);
1494 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1496 /* Does it need write permission? */
1497 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1498 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1502 /* IPC services are limited */
1503 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1504 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1508 /* This call needs to be run as root */
1509 change_to_root_user();
1512 /* load service specific parameters */
1514 if (req->encrypted) {
1515 conn->encrypted_tid = true;
1516 /* encrypted required from now on. */
1517 conn->encrypt_level = Required;
1518 } else if (ENCRYPTION_REQUIRED(conn)) {
1519 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1520 exit_server_cleanly("encryption required "
1526 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1527 (flags & (AS_USER|DO_CHDIR)
1529 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 conn->num_smb_operations++;
1535 /* does this protocol need to be run as guest? */
1536 if ((flags & AS_GUEST)
1537 && (!change_to_guest() ||
1538 !check_access(sconn->sock, lp_hostsallow(-1),
1539 lp_hostsdeny(-1)))) {
1540 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1544 smb_messages[type].fn(req);
1548 /****************************************************************************
1549 Construct a reply to the incoming packet.
1550 ****************************************************************************/
1552 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1553 uint32_t seqnum, bool encrypted,
1554 struct smb_perfcount_data *deferred_pcd)
1556 connection_struct *conn;
1557 struct smb_request *req;
1559 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1560 smb_panic("could not allocate smb_request");
1563 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1564 unread_bytes, encrypted, seqnum)) {
1565 exit_server_cleanly("Invalid SMB request");
1568 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1570 /* we popped this message off the queue - keep original perf data */
1572 req->pcd = *deferred_pcd;
1574 SMB_PERFCOUNT_START(&req->pcd);
1575 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1576 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1579 conn = switch_message(req->cmd, req, size);
1581 if (req->unread_bytes) {
1582 /* writeX failed. drain socket. */
1583 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1584 req->unread_bytes) {
1585 smb_panic("failed to drain pending bytes");
1587 req->unread_bytes = 0;
1595 if (req->outbuf == NULL) {
1599 if (CVAL(req->outbuf,0) == 0) {
1600 show_msg((char *)req->outbuf);
1603 if (!srv_send_smb(req->sconn->sock,
1604 (char *)req->outbuf,
1605 true, req->seqnum+1,
1606 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1608 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1616 /****************************************************************************
1617 Process an smb from the client
1618 ****************************************************************************/
1619 static void process_smb(struct smbd_server_connection *conn,
1620 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1621 uint32_t seqnum, bool encrypted,
1622 struct smb_perfcount_data *deferred_pcd)
1624 int msg_type = CVAL(inbuf,0);
1626 DO_PROFILE_INC(smb_count);
1628 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1630 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1632 (unsigned int)unread_bytes ));
1634 if (msg_type != 0) {
1636 * NetBIOS session request, keepalive, etc.
1638 reply_special(conn, (char *)inbuf);
1642 if (smbd_server_conn->using_smb2) {
1643 /* At this point we're not really using smb2,
1644 * we make the decision here.. */
1645 if (smbd_is_smb2_header(inbuf, nread)) {
1646 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1648 } else if (nread >= smb_size && valid_smb_header(inbuf)
1649 && CVAL(inbuf, smb_com) != 0x72) {
1650 /* This is a non-negprot SMB1 packet.
1651 Disable SMB2 from now on. */
1652 smbd_server_conn->using_smb2 = false;
1656 show_msg((char *)inbuf);
1658 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1662 conn->smb1.num_requests++;
1664 /* The timeout_processing function isn't run nearly
1665 often enough to implement 'max log size' without
1666 overrunning the size of the file by many megabytes.
1667 This is especially true if we are running at debug
1668 level 10. Checking every 50 SMBs is a nice
1669 tradeoff of performance vs log file size overrun. */
1671 if ((conn->smb1.num_requests % 50) == 0 &&
1672 need_to_check_log_size()) {
1673 change_to_root_user();
1678 /****************************************************************************
1679 Return a string containing the function name of a SMB command.
1680 ****************************************************************************/
1682 const char *smb_fn_name(int type)
1684 const char *unknown_name = "SMBunknown";
1686 if (smb_messages[type].name == NULL)
1687 return(unknown_name);
1689 return(smb_messages[type].name);
1692 /****************************************************************************
1693 Helper functions for contruct_reply.
1694 ****************************************************************************/
1696 void add_to_common_flags2(uint32 v)
1701 void remove_from_common_flags2(uint32 v)
1703 common_flags2 &= ~v;
1706 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1709 srv_set_message(outbuf,0,0,false);
1711 SCVAL(outbuf, smb_com, req->cmd);
1712 SIVAL(outbuf,smb_rcls,0);
1713 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1714 SSVAL(outbuf,smb_flg2,
1715 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1717 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1719 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1720 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1721 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1722 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1725 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1727 construct_reply_common(req, (char *)req->inbuf, outbuf);
1731 * How many bytes have we already accumulated up to the current wct field
1735 size_t req_wct_ofs(struct smb_request *req)
1739 if (req->chain_outbuf == NULL) {
1742 buf_size = talloc_get_size(req->chain_outbuf);
1743 if ((buf_size % 4) != 0) {
1744 buf_size += (4 - (buf_size % 4));
1746 return buf_size - 4;
1750 * Hack around reply_nterror & friends not being aware of chained requests,
1751 * generating illegal (i.e. wct==0) chain replies.
1754 static void fixup_chain_error_packet(struct smb_request *req)
1756 uint8_t *outbuf = req->outbuf;
1758 reply_outbuf(req, 2, 0);
1759 memcpy(req->outbuf, outbuf, smb_wct);
1760 TALLOC_FREE(outbuf);
1761 SCVAL(req->outbuf, smb_vwv0, 0xff);
1765 * @brief Find the smb_cmd offset of the last command pushed
1766 * @param[in] buf The buffer we're building up
1767 * @retval Where can we put our next andx cmd?
1769 * While chaining requests, the "next" request we're looking at needs to put
1770 * its SMB_Command before the data the previous request already built up added
1771 * to the chain. Find the offset to the place where we have to put our cmd.
1774 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1779 cmd = CVAL(buf, smb_com);
1781 SMB_ASSERT(is_andx_req(cmd));
1785 while (CVAL(buf, ofs) != 0xff) {
1787 if (!is_andx_req(CVAL(buf, ofs))) {
1792 * ofs is from start of smb header, so add the 4 length
1793 * bytes. The next cmd is right after the wct field.
1795 ofs = SVAL(buf, ofs+2) + 4 + 1;
1797 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1805 * @brief Do the smb chaining at a buffer level
1806 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1807 * @param[in] smb_command The command that we want to issue
1808 * @param[in] wct How many words?
1809 * @param[in] vwv The words, already in network order
1810 * @param[in] bytes_alignment How shall we align "bytes"?
1811 * @param[in] num_bytes How many bytes?
1812 * @param[in] bytes The data the request ships
1814 * smb_splice_chain() adds the vwv and bytes to the request already present in
1818 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1819 uint8_t wct, const uint16_t *vwv,
1820 size_t bytes_alignment,
1821 uint32_t num_bytes, const uint8_t *bytes)
1824 size_t old_size, new_size;
1826 size_t chain_padding = 0;
1827 size_t bytes_padding = 0;
1830 old_size = talloc_get_size(*poutbuf);
1833 * old_size == smb_wct means we're pushing the first request in for
1837 first_request = (old_size == smb_wct);
1839 if (!first_request && ((old_size % 4) != 0)) {
1841 * Align the wct field of subsequent requests to a 4-byte
1844 chain_padding = 4 - (old_size % 4);
1848 * After the old request comes the new wct field (1 byte), the vwv's
1849 * and the num_bytes field. After at we might need to align the bytes
1850 * given to us to "bytes_alignment", increasing the num_bytes value.
1853 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1855 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1856 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1859 new_size += bytes_padding + num_bytes;
1861 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1862 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1863 (unsigned)new_size));
1867 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1868 if (outbuf == NULL) {
1869 DEBUG(0, ("talloc failed\n"));
1874 if (first_request) {
1875 SCVAL(outbuf, smb_com, smb_command);
1877 size_t andx_cmd_ofs;
1879 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1880 DEBUG(1, ("invalid command chain\n"));
1881 *poutbuf = TALLOC_REALLOC_ARRAY(
1882 NULL, *poutbuf, uint8_t, old_size);
1886 if (chain_padding != 0) {
1887 memset(outbuf + old_size, 0, chain_padding);
1888 old_size += chain_padding;
1891 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1892 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1898 * Push the chained request:
1903 SCVAL(outbuf, ofs, wct);
1910 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1911 ofs += sizeof(uint16_t) * wct;
1917 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1918 ofs += sizeof(uint16_t);
1924 if (bytes_padding != 0) {
1925 memset(outbuf + ofs, 0, bytes_padding);
1926 ofs += bytes_padding;
1933 memcpy(outbuf + ofs, bytes, num_bytes);
1938 /****************************************************************************
1939 Construct a chained reply and add it to the already made reply
1940 ****************************************************************************/
1942 void chain_reply(struct smb_request *req)
1944 size_t smblen = smb_len(req->inbuf);
1945 size_t already_used, length_needed;
1947 uint32_t chain_offset; /* uint32_t to avoid overflow */
1954 if (IVAL(req->outbuf, smb_rcls) != 0) {
1955 fixup_chain_error_packet(req);
1959 * Any of the AndX requests and replies have at least a wct of
1960 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1961 * beginning of the SMB header to the next wct field.
1963 * None of the AndX requests put anything valuable in vwv[0] and [1],
1964 * so we can overwrite it here to form the chain.
1967 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1968 if (req->chain_outbuf == NULL) {
1969 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1970 req, req->outbuf, uint8_t,
1971 smb_len(req->outbuf) + 4);
1972 if (req->chain_outbuf == NULL) {
1973 smb_panic("talloc failed");
1981 * Here we assume that this is the end of the chain. For that we need
1982 * to set "next command" to 0xff and the offset to 0. If we later find
1983 * more commands in the chain, this will be overwritten again.
1986 SCVAL(req->outbuf, smb_vwv0, 0xff);
1987 SCVAL(req->outbuf, smb_vwv0+1, 0);
1988 SSVAL(req->outbuf, smb_vwv1, 0);
1990 if (req->chain_outbuf == NULL) {
1992 * In req->chain_outbuf we collect all the replies. Start the
1993 * chain by copying in the first reply.
1995 * We do the realloc because later on we depend on
1996 * talloc_get_size to determine the length of
1997 * chain_outbuf. The reply_xxx routines might have
1998 * over-allocated (reply_pipe_read_and_X used to be such an
2001 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2002 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2003 if (req->chain_outbuf == NULL) {
2004 smb_panic("talloc failed");
2009 * Update smb headers where subsequent chained commands
2010 * may have updated them.
2012 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2013 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2015 if (!smb_splice_chain(&req->chain_outbuf,
2016 CVAL(req->outbuf, smb_com),
2017 CVAL(req->outbuf, smb_wct),
2018 (uint16_t *)(req->outbuf + smb_vwv),
2019 0, smb_buflen(req->outbuf),
2020 (uint8_t *)smb_buf(req->outbuf))) {
2023 TALLOC_FREE(req->outbuf);
2027 * We use the old request's vwv field to grab the next chained command
2028 * and offset into the chained fields.
2031 chain_cmd = CVAL(req->vwv+0, 0);
2032 chain_offset = SVAL(req->vwv+1, 0);
2034 if (chain_cmd == 0xff) {
2036 * End of chain, no more requests from the client. So ship the
2039 smb_setlen((char *)(req->chain_outbuf),
2040 talloc_get_size(req->chain_outbuf) - 4);
2042 if (!srv_send_smb(req->sconn->sock, (char *)req->chain_outbuf,
2043 true, req->seqnum+1,
2044 IS_CONN_ENCRYPTED(req->conn)
2047 exit_server_cleanly("chain_reply: srv_send_smb "
2050 TALLOC_FREE(req->chain_outbuf);
2055 /* add a new perfcounter for this element of chain */
2056 SMB_PERFCOUNT_ADD(&req->pcd);
2057 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2058 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2061 * Check if the client tries to fool us. The request so far uses the
2062 * space to the end of the byte buffer in the request just
2063 * processed. The chain_offset can't point into that area. If that was
2064 * the case, we could end up with an endless processing of the chain,
2065 * we would always handle the same request.
2068 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2069 if (chain_offset < already_used) {
2074 * Next check: Make sure the chain offset does not point beyond the
2075 * overall smb request length.
2078 length_needed = chain_offset+1; /* wct */
2079 if (length_needed > smblen) {
2084 * Now comes the pointer magic. Goal here is to set up req->vwv and
2085 * req->buf correctly again to be able to call the subsequent
2086 * switch_message(). The chain offset (the former vwv[1]) points at
2087 * the new wct field.
2090 wct = CVAL(smb_base(req->inbuf), chain_offset);
2093 * Next consistency check: Make the new vwv array fits in the overall
2097 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2098 if (length_needed > smblen) {
2101 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2104 * Now grab the new byte buffer....
2107 buflen = SVAL(vwv+wct, 0);
2110 * .. and check that it fits.
2113 length_needed += buflen;
2114 if (length_needed > smblen) {
2117 buf = (uint8_t *)(vwv+wct+1);
2119 req->cmd = chain_cmd;
2122 req->buflen = buflen;
2125 switch_message(chain_cmd, req, smblen);
2127 if (req->outbuf == NULL) {
2129 * This happens if the chained command has suspended itself or
2130 * if it has called srv_send_smb() itself.
2136 * We end up here if the chained command was not itself chained or
2137 * suspended, but for example a close() command. We now need to splice
2138 * the chained commands' outbuf into the already built up chain_outbuf
2139 * and ship the result.
2145 * We end up here if there's any error in the chain syntax. Report a
2146 * DOS error, just like Windows does.
2148 reply_force_doserror(req, ERRSRV, ERRerror);
2149 fixup_chain_error_packet(req);
2153 * This scary statement intends to set the
2154 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2155 * to the value req->outbuf carries
2157 SSVAL(req->chain_outbuf, smb_flg2,
2158 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2159 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2162 * Transfer the error codes from the subrequest to the main one
2164 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2165 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2167 if (!smb_splice_chain(&req->chain_outbuf,
2168 CVAL(req->outbuf, smb_com),
2169 CVAL(req->outbuf, smb_wct),
2170 (uint16_t *)(req->outbuf + smb_vwv),
2171 0, smb_buflen(req->outbuf),
2172 (uint8_t *)smb_buf(req->outbuf))) {
2173 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2175 TALLOC_FREE(req->outbuf);
2177 smb_setlen((char *)(req->chain_outbuf),
2178 talloc_get_size(req->chain_outbuf) - 4);
2180 show_msg((char *)(req->chain_outbuf));
2182 if (!srv_send_smb(req->sconn->sock, (char *)req->chain_outbuf,
2183 true, req->seqnum+1,
2184 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2186 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2188 TALLOC_FREE(req->chain_outbuf);
2192 /****************************************************************************
2193 Check if services need reloading.
2194 ****************************************************************************/
2196 static void check_reload(struct messaging_context *msg_ctx, time_t t)
2198 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2200 if(last_smb_conf_reload_time == 0) {
2201 last_smb_conf_reload_time = t;
2202 /* Our printing subsystem might not be ready at smbd start up.
2203 Then no printer is available till the first printers check
2204 is performed. A lower initial interval circumvents this. */
2205 if ( printcap_cache_time > 60 )
2206 last_printer_reload_time = t - printcap_cache_time + 60;
2208 last_printer_reload_time = t;
2211 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2212 /* randomize over 60 second the printcap reload to avoid all
2213 * process hitting cupsd at the same time */
2214 int time_range = 60;
2216 last_printer_reload_time += random() % time_range;
2220 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2221 reload_services(msg_ctx, True);
2222 last_smb_conf_reload_time = t;
2225 /* 'printcap cache time = 0' disable the feature */
2227 if ( printcap_cache_time != 0 )
2229 /* see if it's time to reload or if the clock has been set back */
2231 if ( (t >= last_printer_reload_time+printcap_cache_time)
2232 || (t-last_printer_reload_time < 0) )
2234 DEBUG( 3,( "Printcap cache time expired.\n"));
2235 reload_printers(msg_ctx);
2236 last_printer_reload_time = t;
2241 static bool fd_is_readable(int fd)
2244 struct timeval timeout = {0, };
2250 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2254 return FD_ISSET(fd, &fds);
2257 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2259 /* TODO: make write nonblocking */
2262 static void smbd_server_connection_read_handler(
2263 struct smbd_server_connection *conn, int fd)
2265 uint8_t *inbuf = NULL;
2266 size_t inbuf_len = 0;
2267 size_t unread_bytes = 0;
2268 bool encrypted = false;
2269 TALLOC_CTX *mem_ctx = talloc_tos();
2273 bool from_client = (conn->sock == fd);
2276 smbd_lock_socket(conn);
2278 if (!fd_is_readable(fd)) {
2279 DEBUG(10,("the echo listener was faster\n"));
2280 smbd_unlock_socket(conn);
2284 /* TODO: make this completely nonblocking */
2285 status = receive_smb_talloc(mem_ctx, fd,
2286 (char **)(void *)&inbuf,
2290 &inbuf_len, &seqnum,
2291 false /* trusted channel */);
2292 smbd_unlock_socket(conn);
2294 /* TODO: make this completely nonblocking */
2295 status = receive_smb_talloc(mem_ctx, fd,
2296 (char **)(void *)&inbuf,
2300 &inbuf_len, &seqnum,
2301 true /* trusted channel */);
2304 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2307 if (NT_STATUS_IS_ERR(status)) {
2308 exit_server_cleanly("failed to receive smb request");
2310 if (!NT_STATUS_IS_OK(status)) {
2315 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2316 seqnum, encrypted, NULL);
2319 static void smbd_server_connection_handler(struct event_context *ev,
2320 struct fd_event *fde,
2324 struct smbd_server_connection *conn = talloc_get_type(private_data,
2325 struct smbd_server_connection);
2327 if (flags & EVENT_FD_WRITE) {
2328 smbd_server_connection_write_handler(conn);
2331 if (flags & EVENT_FD_READ) {
2332 smbd_server_connection_read_handler(conn, conn->sock);
2337 static void smbd_server_echo_handler(struct event_context *ev,
2338 struct fd_event *fde,
2342 struct smbd_server_connection *conn = talloc_get_type(private_data,
2343 struct smbd_server_connection);
2345 if (flags & EVENT_FD_WRITE) {
2346 smbd_server_connection_write_handler(conn);
2349 if (flags & EVENT_FD_READ) {
2350 smbd_server_connection_read_handler(
2351 conn, conn->smb1.echo_handler.trusted_fd);
2356 /****************************************************************************
2357 received when we should release a specific IP
2358 ****************************************************************************/
2359 static void release_ip(const char *ip, void *priv)
2361 char addr[INET6_ADDRSTRLEN];
2364 client_socket_addr(smbd_server_fd(),addr,sizeof(addr));
2366 if (strncmp("::ffff:", addr, 7) == 0) {
2370 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2371 /* we can't afford to do a clean exit - that involves
2372 database writes, which would potentially mean we
2373 are still running after the failover has finished -
2374 we have to get rid of this process ID straight
2376 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2378 /* note we must exit with non-zero status so the unclean handler gets
2379 called in the parent, so that the brl database is tickled */
2384 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2385 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2387 release_ip((char *)data->data, NULL);
2390 #ifdef CLUSTER_SUPPORT
2391 static int client_get_tcp_info(struct sockaddr_storage *server,
2392 struct sockaddr_storage *client)
2395 if (server_fd == -1) {
2398 length = sizeof(*server);
2399 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2402 length = sizeof(*client);
2403 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2411 * Send keepalive packets to our client
2413 static bool keepalive_fn(const struct timeval *now, void *private_data)
2415 struct smbd_server_connection *sconn = smbd_server_conn;
2418 if (sconn->using_smb2) {
2419 /* Don't do keepalives on an SMB2 connection. */
2423 smbd_lock_socket(smbd_server_conn);
2424 ret = send_keepalive(sconn->sock);
2425 smbd_unlock_socket(smbd_server_conn);
2428 char addr[INET6_ADDRSTRLEN];
2430 * Try and give an error message saying what
2433 DEBUG(0, ("send_keepalive failed for client %s. "
2434 "Error %s - exiting\n",
2435 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2443 * Do the recurring check if we're idle
2445 static bool deadtime_fn(const struct timeval *now, void *private_data)
2447 struct smbd_server_connection *sconn =
2448 (struct smbd_server_connection *)private_data;
2450 if (sconn->using_smb2) {
2451 /* TODO: implement real idle check */
2452 if (sconn->smb2.sessions.list) {
2455 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2456 messaging_send(sconn->msg_ctx, procid_self(),
2457 MSG_SHUTDOWN, &data_blob_null);
2461 if ((conn_num_open(sconn) == 0)
2462 || (conn_idle_all(sconn, now->tv_sec))) {
2463 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2464 messaging_send(sconn->msg_ctx, procid_self(),
2465 MSG_SHUTDOWN, &data_blob_null);
2473 * Do the recurring log file and smb.conf reload checks.
2476 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2478 struct messaging_context *msg_ctx = talloc_get_type_abort(
2479 private_data, struct messaging_context);
2480 change_to_root_user();
2482 /* update printer queue caches if necessary */
2483 update_monitored_printq_cache(msg_ctx);
2485 /* check if we need to reload services */
2486 check_reload(msg_ctx, time(NULL));
2488 /* Change machine password if neccessary. */
2489 attempt_machine_password_change();
2492 * Force a log file check.
2494 force_check_log_size();
2499 static int create_unlink_tmp(const char *dir)
2504 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2505 if (fname == NULL) {
2509 fd = mkstemp(fname);
2514 if (unlink(fname) == -1) {
2515 int sys_errno = errno;
2525 struct smbd_echo_state {
2526 struct tevent_context *ev;
2527 struct iovec *pending;
2528 struct smbd_server_connection *sconn;
2531 struct tevent_fd *parent_fde;
2533 struct tevent_fd *read_fde;
2534 struct tevent_req *write_req;
2537 static void smbd_echo_writer_done(struct tevent_req *req);
2539 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2543 if (state->write_req != NULL) {
2547 num_pending = talloc_array_length(state->pending);
2548 if (num_pending == 0) {
2552 state->write_req = writev_send(state, state->ev, NULL,
2553 state->parent_pipe, false,
2554 state->pending, num_pending);
2555 if (state->write_req == NULL) {
2556 DEBUG(1, ("writev_send failed\n"));
2560 talloc_steal(state->write_req, state->pending);
2561 state->pending = NULL;
2563 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2567 static void smbd_echo_writer_done(struct tevent_req *req)
2569 struct smbd_echo_state *state = tevent_req_callback_data(
2570 req, struct smbd_echo_state);
2574 written = writev_recv(req, &err);
2576 state->write_req = NULL;
2577 if (written == -1) {
2578 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2581 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2582 smbd_echo_activate_writer(state);
2585 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2588 struct smb_request req;
2589 uint16_t num_replies;
2594 if (inbuf_len < smb_size) {
2595 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2598 if (!valid_smb_header(inbuf)) {
2599 DEBUG(10, ("Got invalid SMB header\n"));
2603 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2609 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2610 smb_messages[req.cmd].name
2611 ? smb_messages[req.cmd].name : "unknown"));
2613 if (req.cmd != SMBecho) {
2620 num_replies = SVAL(req.vwv+0, 0);
2621 if (num_replies != 1) {
2622 /* Not a Windows "Hey, you're still there?" request */
2626 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2628 DEBUG(10, ("create_outbuf failed\n"));
2631 req.outbuf = (uint8_t *)outbuf;
2633 SSVAL(req.outbuf, smb_vwv0, num_replies);
2635 if (req.buflen > 0) {
2636 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2639 out_len = smb_len(req.outbuf) + 4;
2641 ok = srv_send_smb(req.sconn->sock,
2645 TALLOC_FREE(outbuf);
2653 static void smbd_echo_exit(struct tevent_context *ev,
2654 struct tevent_fd *fde, uint16_t flags,
2657 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2661 static void smbd_echo_reader(struct tevent_context *ev,
2662 struct tevent_fd *fde, uint16_t flags,
2665 struct smbd_echo_state *state = talloc_get_type_abort(
2666 private_data, struct smbd_echo_state);
2667 struct smbd_server_connection *sconn = state->sconn;
2668 size_t unread, num_pending;
2671 uint32_t seqnum = 0;
2674 bool encrypted = false;
2678 ok = smbd_lock_socket_internal(sconn);
2680 DEBUG(0, ("%s: failed to lock socket\n",
2685 if (!fd_is_readable(sconn->sock)) {
2686 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2687 (int)sys_getpid()));
2688 ok = smbd_unlock_socket_internal(sconn);
2690 DEBUG(1, ("%s: failed to unlock socket in\n",
2697 num_pending = talloc_array_length(state->pending);
2698 tmp = talloc_realloc(state, state->pending, struct iovec,
2701 DEBUG(1, ("talloc_realloc failed\n"));
2704 state->pending = tmp;
2706 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2708 status = receive_smb_talloc(state->pending, sconn->sock,
2709 (char **)(void *)&state->pending[num_pending].iov_base,
2713 &state->pending[num_pending].iov_len,
2715 false /* trusted_channel*/);
2716 if (!NT_STATUS_IS_OK(status)) {
2717 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2718 (int)sys_getpid(), nt_errstr(status)));
2722 ok = smbd_unlock_socket_internal(sconn);
2724 DEBUG(1, ("%s: failed to unlock socket in\n",
2730 * place the seqnum in the packet so that the main process can reply
2733 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2734 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2736 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2737 state->pending[num_pending].iov_len,
2740 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2741 /* no check, shrinking by some bytes does not fail */
2742 state->pending = talloc_realloc(state, state->pending,
2746 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2747 smbd_echo_activate_writer(state);
2751 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2754 struct smbd_echo_state *state;
2756 state = talloc_zero(sconn, struct smbd_echo_state);
2757 if (state == NULL) {
2758 DEBUG(1, ("talloc failed\n"));
2761 state->sconn = sconn;
2762 state->parent_pipe = parent_pipe;
2763 state->ev = s3_tevent_context_init(state);
2764 if (state->ev == NULL) {
2765 DEBUG(1, ("tevent_context_init failed\n"));
2769 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2770 TEVENT_FD_READ, smbd_echo_exit,
2772 if (state->parent_fde == NULL) {
2773 DEBUG(1, ("tevent_add_fd failed\n"));
2777 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2778 TEVENT_FD_READ, smbd_echo_reader,
2780 if (state->read_fde == NULL) {
2781 DEBUG(1, ("tevent_add_fd failed\n"));
2787 if (tevent_loop_once(state->ev) == -1) {
2788 DEBUG(1, ("tevent_loop_once failed: %s\n",
2797 * Handle SMBecho requests in a forked child process
2799 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2801 int listener_pipe[2];
2805 res = pipe(listener_pipe);
2807 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2810 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2811 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2812 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2820 close(listener_pipe[0]);
2822 status = reinit_after_fork(sconn->msg_ctx,
2823 smbd_event_context(),
2824 procid_self(), false);
2825 if (!NT_STATUS_IS_OK(status)) {
2826 DEBUG(1, ("reinit_after_fork failed: %s\n",
2827 nt_errstr(status)));
2830 smbd_echo_loop(sconn, listener_pipe[1]);
2833 close(listener_pipe[1]);
2834 listener_pipe[1] = -1;
2835 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2837 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2840 * Without smb signing this is the same as the normal smbd
2841 * listener. This needs to change once signing comes in.
2843 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2845 sconn->smb1.echo_handler.trusted_fd,
2847 smbd_server_echo_handler,
2849 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2850 DEBUG(1, ("event_add_fd failed\n"));
2857 if (listener_pipe[0] != -1) {
2858 close(listener_pipe[0]);
2860 if (listener_pipe[1] != -1) {
2861 close(listener_pipe[1]);
2863 sconn->smb1.echo_handler.trusted_fd = -1;
2864 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2865 close(sconn->smb1.echo_handler.socket_lock_fd);
2867 sconn->smb1.echo_handler.trusted_fd = -1;
2868 sconn->smb1.echo_handler.socket_lock_fd = -1;
2872 /****************************************************************************
2873 Process commands from the client
2874 ****************************************************************************/
2876 void smbd_process(struct smbd_server_connection *sconn)
2878 TALLOC_CTX *frame = talloc_stackframe();
2879 struct sockaddr_storage ss;
2880 struct sockaddr *sa = NULL;
2882 struct tsocket_address *local_address = NULL;
2883 struct tsocket_address *remote_address = NULL;
2884 const char *remaddr = NULL;
2887 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2888 lp_security() != SEC_SHARE &&
2889 !lp_async_smb_echo_handler()) {
2891 * We're not making the desion here,
2892 * we're just allowing the client
2893 * to decide between SMB1 and SMB2
2894 * with the first negprot
2897 sconn->using_smb2 = true;
2900 /* Ensure child is set to blocking mode */
2901 set_blocking(sconn->sock,True);
2903 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2904 set_socket_options(sconn->sock, lp_socket_options());
2906 sa = (struct sockaddr *)(void *)&ss;
2907 sa_len = sizeof(ss);
2908 ret = getpeername(sconn->sock, sa, &sa_len);
2910 int level = (errno == ENOTCONN)?2:0;
2911 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2912 exit_server_cleanly("getpeername() failed.\n");
2914 ret = tsocket_address_bsd_from_sockaddr(sconn,
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 sa = (struct sockaddr *)(void *)&ss;
2924 sa_len = sizeof(ss);
2925 ret = getsockname(sconn->sock, sa, &sa_len);
2927 int level = (errno == ENOTCONN)?2:0;
2928 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2929 exit_server_cleanly("getsockname() failed.\n");
2931 ret = tsocket_address_bsd_from_sockaddr(sconn,
2935 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2936 __location__, strerror(errno)));
2937 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2940 sconn->local_address = local_address;
2941 sconn->remote_address = remote_address;
2943 if (tsocket_address_is_inet(remote_address, "ip")) {
2944 remaddr = tsocket_address_inet_addr_string(
2945 sconn->remote_address,
2947 if (remaddr == NULL) {
2951 remaddr = "0.0.0.0";
2954 /* this is needed so that we get decent entries
2955 in smbstatus for port 445 connects */
2956 set_remote_machine_name(remaddr, false);
2957 reload_services(sconn->msg_ctx, true);
2960 * Before the first packet, check the global hosts allow/ hosts deny
2961 * parameters before doing any parsing of packets passed to us by the
2962 * client. This prevents attacks on our parsing code from hosts not in
2963 * the hosts allow list.
2966 if (!check_access(sconn->sock, lp_hostsallow(-1),
2967 lp_hostsdeny(-1))) {
2969 * send a negative session response "not listening on calling
2972 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2973 DEBUG( 1, ("Connection denied from %s to %s\n",
2974 tsocket_address_string(remote_address, talloc_tos()),
2975 tsocket_address_string(local_address, talloc_tos())));
2976 (void)srv_send_smb(sconn->sock,(char *)buf, false,
2978 exit_server_cleanly("connection denied");
2981 DEBUG(10, ("Connection allowed from %s to %s\n",
2982 tsocket_address_string(remote_address, talloc_tos()),
2983 tsocket_address_string(local_address, talloc_tos())));
2987 smb_perfcount_init();
2989 if (!init_account_policy()) {
2990 exit_server("Could not open account policy tdb.\n");
2993 if (*lp_rootdir()) {
2994 if (chroot(lp_rootdir()) != 0) {
2995 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2996 exit_server("Failed to chroot()");
2998 if (chdir("/") == -1) {
2999 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3000 exit_server("Failed to chroot()");
3002 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3005 if (!srv_init_signing(sconn)) {
3006 exit_server("Failed to init smb_signing");
3009 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3010 exit_server("Failed to fork echo handler");
3014 if (!init_oplocks(sconn->msg_ctx))
3015 exit_server("Failed to init oplocks");
3017 /* register our message handlers */
3018 messaging_register(sconn->msg_ctx, NULL,
3019 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3020 messaging_register(sconn->msg_ctx, NULL,
3021 MSG_SMB_RELEASE_IP, msg_release_ip);
3022 messaging_register(sconn->msg_ctx, NULL,
3023 MSG_SMB_CLOSE_FILE, msg_close_file);
3026 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3027 * MSGs to all child processes
3029 messaging_deregister(sconn->msg_ctx,
3031 messaging_register(sconn->msg_ctx, NULL,
3032 MSG_DEBUG, debug_message);
3034 if ((lp_keepalive() != 0)
3035 && !(event_add_idle(smbd_event_context(), NULL,
3036 timeval_set(lp_keepalive(), 0),
3037 "keepalive", keepalive_fn,
3039 DEBUG(0, ("Could not add keepalive event\n"));
3043 if (!(event_add_idle(smbd_event_context(), NULL,
3044 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3045 "deadtime", deadtime_fn, sconn))) {
3046 DEBUG(0, ("Could not add deadtime event\n"));
3050 if (!(event_add_idle(smbd_event_context(), NULL,
3051 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3052 "housekeeping", housekeeping_fn,
3054 DEBUG(0, ("Could not add housekeeping event\n"));
3058 #ifdef CLUSTER_SUPPORT
3060 if (lp_clustering()) {
3062 * We need to tell ctdb about our client's TCP
3063 * connection, so that for failover ctdbd can send
3064 * tickle acks, triggering a reconnection by the
3068 struct sockaddr_storage srv, clnt;
3070 if (client_get_tcp_info(&srv, &clnt) == 0) {
3074 status = ctdbd_register_ips(
3075 messaging_ctdbd_connection(procid_self()),
3076 &srv, &clnt, release_ip, NULL);
3078 if (!NT_STATUS_IS_OK(status)) {
3079 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3080 nt_errstr(status)));
3084 DEBUG(0,("Unable to get tcp info for "
3085 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3092 sconn->nbt.got_session = false;
3094 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3096 sconn->smb1.sessions.done_sesssetup = false;
3097 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3098 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3099 /* users from session setup */
3100 sconn->smb1.sessions.session_userlist = NULL;
3101 /* workgroup from session setup. */
3102 sconn->smb1.sessions.session_workgroup = NULL;
3103 /* this holds info on user ids that are already validated for this VC */
3104 sconn->smb1.sessions.validated_users = NULL;
3105 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3106 sconn->smb1.sessions.num_validated_vuids = 0;
3109 if (!init_dptrs(sconn)) {
3110 exit_server("init_dptrs() failed");
3113 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3117 smbd_server_connection_handler,
3119 if (!sconn->smb1.fde) {
3120 exit_server("failed to create smbd_server_connection fde");
3128 frame = talloc_stackframe_pool(8192);
3132 status = smbd_server_connection_loop_once(sconn);
3133 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3134 !NT_STATUS_IS_OK(status)) {
3135 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3136 " exiting\n", nt_errstr(status)));
3143 exit_server_cleanly(NULL);
3146 bool req_is_in_chain(struct smb_request *req)
3148 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3150 * We're right now handling a subsequent request, so we must
3156 if (!is_andx_req(req->cmd)) {
3162 * Okay, an illegal request, but definitely not chained :-)
3167 return (CVAL(req->vwv+0, 0) != 0xFF);