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/srv_dfs.h"
24 #include "../librpc/gen_ndr/srv_dssetup.h"
25 #include "../librpc/gen_ndr/srv_echo.h"
26 #include "../librpc/gen_ndr/srv_eventlog.h"
27 #include "../librpc/gen_ndr/srv_initshutdown.h"
28 #include "../librpc/gen_ndr/srv_lsa.h"
29 #include "../librpc/gen_ndr/srv_netlogon.h"
30 #include "../librpc/gen_ndr/srv_ntsvcs.h"
31 #include "../librpc/gen_ndr/srv_samr.h"
32 #include "../librpc/gen_ndr/srv_spoolss.h"
33 #include "../librpc/gen_ndr/srv_srvsvc.h"
34 #include "../librpc/gen_ndr/srv_svcctl.h"
35 #include "../librpc/gen_ndr/srv_winreg.h"
36 #include "../librpc/gen_ndr/srv_wkssvc.h"
38 extern bool global_machine_password_needs_changing;
40 static void construct_reply_common(struct smb_request *req, const char *inbuf,
42 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
44 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
48 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
52 smbd_server_conn->smb1.echo_handler.ref_count++;
54 if (smbd_server_conn->smb1.echo_handler.ref_count > 1) {
58 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
60 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
61 SMB_F_SETLKW, 0, 0, F_WRLCK);
66 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
71 void smbd_lock_socket(struct smbd_server_connection *sconn)
73 if (!smbd_lock_socket_internal(sconn)) {
74 exit_server_cleanly("failed to lock socket");
78 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
82 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
86 smbd_server_conn->smb1.echo_handler.ref_count--;
88 if (smbd_server_conn->smb1.echo_handler.ref_count > 0) {
92 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
93 SMB_F_SETLKW, 0, 0, F_UNLCK);
98 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
103 void smbd_unlock_socket(struct smbd_server_connection *sconn)
105 if (!smbd_unlock_socket_internal(sconn)) {
106 exit_server_cleanly("failed to unlock socket");
110 /* Accessor function for smb_read_error for smbd functions. */
112 /****************************************************************************
114 ****************************************************************************/
116 bool srv_send_smb(int fd, char *buffer,
117 bool do_signing, uint32_t seqnum,
119 struct smb_perfcount_data *pcd)
124 char *buf_out = buffer;
126 smbd_lock_socket(smbd_server_conn);
129 /* Sign the outgoing packet if required. */
130 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
134 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
135 if (!NT_STATUS_IS_OK(status)) {
136 DEBUG(0, ("send_smb: SMB encryption failed "
137 "on outgoing packet! Error %s\n",
138 nt_errstr(status) ));
143 len = smb_len(buf_out) + 4;
145 ret = write_data(fd,buf_out+nwritten,len - nwritten);
147 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
148 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
149 srv_free_enc_buffer(buf_out);
153 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
154 srv_free_enc_buffer(buf_out);
156 SMB_PERFCOUNT_END(pcd);
158 smbd_unlock_socket(smbd_server_conn);
162 /*******************************************************************
163 Setup the word count and byte count for a smb message.
164 ********************************************************************/
166 int srv_set_message(char *buf,
171 if (zero && (num_words || num_bytes)) {
172 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
174 SCVAL(buf,smb_wct,num_words);
175 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
176 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
177 return (smb_size + num_words*2 + num_bytes);
180 static bool valid_smb_header(const uint8_t *inbuf)
182 if (is_encrypted_packet(inbuf)) {
186 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
187 * but it just looks weird to call strncmp for this one.
189 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
192 /* Socket functions for smbd packet processing. */
194 static bool valid_packet_size(size_t len)
197 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
198 * of header. Don't print the error if this fits.... JRA.
201 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
202 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
203 (unsigned long)len));
209 static NTSTATUS read_packet_remainder(int fd, char *buffer,
210 unsigned int timeout, ssize_t len)
216 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
219 /****************************************************************************
220 Attempt a zerocopy writeX read. We know here that len > smb_size-4
221 ****************************************************************************/
224 * Unfortunately, earlier versions of smbclient/libsmbclient
225 * don't send this "standard" writeX header. I've fixed this
226 * for 3.2 but we'll use the old method with earlier versions.
227 * Windows and CIFSFS at least use this standard size. Not
231 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
232 (2*14) + /* word count (including bcc) */ \
235 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
236 const char lenbuf[4],
237 int fd, char **buffer,
238 unsigned int timeout,
242 /* Size of a WRITEX call (+4 byte len). */
243 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
244 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
248 memcpy(writeX_header, lenbuf, 4);
250 status = read_fd_with_timeout(
251 fd, writeX_header + 4,
252 STANDARD_WRITE_AND_X_HEADER_SIZE,
253 STANDARD_WRITE_AND_X_HEADER_SIZE,
256 if (!NT_STATUS_IS_OK(status)) {
261 * Ok - now try and see if this is a possible
265 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
267 * If the data offset is beyond what
268 * we've read, drain the extra bytes.
270 uint16_t doff = SVAL(writeX_header,smb_vwv11);
273 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
274 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
275 if (drain_socket(smbd_server_fd(), drain) != drain) {
276 smb_panic("receive_smb_raw_talloc_partial_read:"
277 " failed to drain pending bytes");
280 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
283 /* Spoof down the length and null out the bcc. */
284 set_message_bcc(writeX_header, 0);
285 newlen = smb_len(writeX_header);
287 /* Copy the header we've written. */
289 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
291 sizeof(writeX_header));
293 if (*buffer == NULL) {
294 DEBUG(0, ("Could not allocate inbuf of length %d\n",
295 (int)sizeof(writeX_header)));
296 return NT_STATUS_NO_MEMORY;
299 /* Work out the remaining bytes. */
300 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
301 *len_ret = newlen + 4;
305 if (!valid_packet_size(len)) {
306 return NT_STATUS_INVALID_PARAMETER;
310 * Not a valid writeX call. Just do the standard
314 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
316 if (*buffer == NULL) {
317 DEBUG(0, ("Could not allocate inbuf of length %d\n",
319 return NT_STATUS_NO_MEMORY;
322 /* Copy in what we already read. */
325 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
326 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
329 status = read_packet_remainder(
330 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
333 if (!NT_STATUS_IS_OK(status)) {
334 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
344 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
345 char **buffer, unsigned int timeout,
346 size_t *p_unread, size_t *plen)
350 int min_recv_size = lp_min_receive_file_size();
355 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
356 if (!NT_STATUS_IS_OK(status)) {
357 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
361 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
362 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
363 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
364 !srv_is_signing_active(smbd_server_conn) &&
365 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
367 return receive_smb_raw_talloc_partial_read(
368 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
371 if (!valid_packet_size(len)) {
372 return NT_STATUS_INVALID_PARAMETER;
376 * The +4 here can't wrap, we've checked the length above already.
379 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
381 if (*buffer == NULL) {
382 DEBUG(0, ("Could not allocate inbuf of length %d\n",
384 return NT_STATUS_NO_MEMORY;
387 memcpy(*buffer, lenbuf, sizeof(lenbuf));
389 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
390 if (!NT_STATUS_IS_OK(status)) {
398 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
399 char **buffer, unsigned int timeout,
400 size_t *p_unread, bool *p_encrypted,
403 bool trusted_channel)
408 *p_encrypted = false;
410 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
412 if (!NT_STATUS_IS_OK(status)) {
416 if (is_encrypted_packet((uint8_t *)*buffer)) {
417 status = srv_decrypt_buffer(*buffer);
418 if (!NT_STATUS_IS_OK(status)) {
419 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
420 "incoming packet! Error %s\n",
421 nt_errstr(status) ));
427 /* Check the incoming SMB signature. */
428 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
429 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
430 "incoming packet!\n"));
431 return NT_STATUS_INVALID_NETWORK_RESPONSE;
439 * Initialize a struct smb_request from an inbuf
442 static bool init_smb_request(struct smb_request *req, const uint8 *inbuf,
443 size_t unread_bytes, bool encrypted,
446 struct smbd_server_connection *sconn = smbd_server_conn;
447 size_t req_size = smb_len(inbuf) + 4;
448 /* Ensure we have at least smb_size bytes. */
449 if (req_size < smb_size) {
450 DEBUG(0,("init_smb_request: invalid request size %u\n",
451 (unsigned int)req_size ));
454 req->cmd = CVAL(inbuf, smb_com);
455 req->flags2 = SVAL(inbuf, smb_flg2);
456 req->smbpid = SVAL(inbuf, smb_pid);
457 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
458 req->seqnum = seqnum;
459 req->vuid = SVAL(inbuf, smb_uid);
460 req->tid = SVAL(inbuf, smb_tid);
461 req->wct = CVAL(inbuf, smb_wct);
462 req->vwv = (uint16_t *)(inbuf+smb_vwv);
463 req->buflen = smb_buflen(inbuf);
464 req->buf = (const uint8_t *)smb_buf(inbuf);
465 req->unread_bytes = unread_bytes;
466 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->allow_smb2) {
609 remove_deferred_open_message_smb2(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->allow_smb2) {
637 schedule_deferred_open_message_smb2(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->allow_smb2) {
698 return open_was_deferred_smb2(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(uint64_t mid,
730 struct timeval *p_request_time,
733 struct pending_message_list *pml;
735 if (smbd_server_conn->allow_smb2) {
736 return get_deferred_open_message_state_smb2(mid,
741 pml = get_deferred_open_message_smb(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,
762 char *private_data, size_t priv_len)
764 struct timeval end_time;
767 return push_deferred_open_message_smb2(req,
774 if (req->unread_bytes) {
775 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
776 "unread_bytes = %u\n",
777 (unsigned int)req->unread_bytes ));
778 smb_panic("push_deferred_open_message_smb: "
779 "logic error unread_bytes != 0" );
782 end_time = timeval_sum(&request_time, &timeout);
784 DEBUG(10,("push_deferred_open_message_smb: pushing message "
785 "len %u mid %llu timeout time [%u.%06u]\n",
786 (unsigned int) smb_len(req->inbuf)+4,
787 (unsigned long long)req->mid,
788 (unsigned int)end_time.tv_sec,
789 (unsigned int)end_time.tv_usec));
791 return push_queued_message(req, request_time, end_time,
792 private_data, priv_len);
796 struct timed_event *te;
797 struct timeval interval;
799 bool (*handler)(const struct timeval *now, void *private_data);
803 static void smbd_idle_event_handler(struct event_context *ctx,
804 struct timed_event *te,
808 struct idle_event *event =
809 talloc_get_type_abort(private_data, struct idle_event);
811 TALLOC_FREE(event->te);
813 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
814 event->name, event->te));
816 if (!event->handler(&now, event->private_data)) {
817 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
818 event->name, event->te));
819 /* Don't repeat, delete ourselves */
824 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
825 event->name, event->te));
827 event->te = event_add_timed(ctx, event,
828 timeval_sum(&now, &event->interval),
829 smbd_idle_event_handler, event);
831 /* We can't do much but fail here. */
832 SMB_ASSERT(event->te != NULL);
835 struct idle_event *event_add_idle(struct event_context *event_ctx,
837 struct timeval interval,
839 bool (*handler)(const struct timeval *now,
843 struct idle_event *result;
844 struct timeval now = timeval_current();
846 result = TALLOC_P(mem_ctx, struct idle_event);
847 if (result == NULL) {
848 DEBUG(0, ("talloc failed\n"));
852 result->interval = interval;
853 result->handler = handler;
854 result->private_data = private_data;
856 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
857 DEBUG(0, ("talloc failed\n"));
862 result->te = event_add_timed(event_ctx, result,
863 timeval_sum(&now, &interval),
864 smbd_idle_event_handler, result);
865 if (result->te == NULL) {
866 DEBUG(0, ("event_add_timed failed\n"));
871 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
875 static void smbd_sig_term_handler(struct tevent_context *ev,
876 struct tevent_signal *se,
882 exit_server_cleanly("termination signal");
885 void smbd_setup_sig_term_handler(void)
887 struct tevent_signal *se;
889 se = tevent_add_signal(smbd_event_context(),
890 smbd_event_context(),
892 smbd_sig_term_handler,
895 exit_server("failed to setup SIGTERM handler");
899 static void smbd_sig_hup_handler(struct tevent_context *ev,
900 struct tevent_signal *se,
906 change_to_root_user();
907 DEBUG(1,("Reloading services after SIGHUP\n"));
908 reload_services(False);
911 void smbd_setup_sig_hup_handler(void)
913 struct tevent_signal *se;
915 se = tevent_add_signal(smbd_event_context(),
916 smbd_event_context(),
918 smbd_sig_hup_handler,
921 exit_server("failed to setup SIGHUP handler");
925 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
932 to.tv_sec = SMBD_SELECT_TIMEOUT;
936 * Setup the select fd sets.
943 * Are there any timed events waiting ? If so, ensure we don't
944 * select for longer than it would take to wait for them.
951 event_add_to_select_args(smbd_event_context(), &now,
952 &r_fds, &w_fds, &to, &maxfd);
955 /* Process a signal and timed events now... */
956 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
957 return NT_STATUS_RETRY;
962 START_PROFILE(smbd_idle);
964 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
967 END_PROFILE(smbd_idle);
971 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
972 return NT_STATUS_RETRY;
977 /* something is wrong. Maybe the socket is dead? */
978 return map_nt_error_from_unix(errno);
981 /* Did we timeout ? */
983 return NT_STATUS_RETRY;
986 /* should not be reached */
987 return NT_STATUS_INTERNAL_ERROR;
991 * Only allow 5 outstanding trans requests. We're allocating memory, so
995 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
998 for (; list != NULL; list = list->next) {
1000 if (list->mid == mid) {
1001 return NT_STATUS_INVALID_PARAMETER;
1007 return NT_STATUS_INSUFFICIENT_RESOURCES;
1010 return NT_STATUS_OK;
1014 These flags determine some of the permissions required to do an operation
1016 Note that I don't set NEED_WRITE on some write operations because they
1017 are used by some brain-dead clients when printing, and I don't want to
1018 force write permissions on print services.
1020 #define AS_USER (1<<0)
1021 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1022 #define TIME_INIT (1<<2)
1023 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1024 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1025 #define DO_CHDIR (1<<6)
1028 define a list of possible SMB messages and their corresponding
1029 functions. Any message that has a NULL function is unimplemented -
1030 please feel free to contribute implementations!
1032 static const struct smb_message_struct {
1034 void (*fn)(struct smb_request *req);
1036 } smb_messages[256] = {
1038 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1039 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1040 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1041 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1042 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1043 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1044 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1045 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1046 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1047 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1048 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1049 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1050 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1051 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1052 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1053 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1054 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1055 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1056 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1057 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1058 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1059 /* 0x15 */ { NULL, NULL, 0 },
1060 /* 0x16 */ { NULL, NULL, 0 },
1061 /* 0x17 */ { NULL, NULL, 0 },
1062 /* 0x18 */ { NULL, NULL, 0 },
1063 /* 0x19 */ { NULL, NULL, 0 },
1064 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1065 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1066 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1067 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1068 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1069 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1070 /* 0x20 */ { "SMBwritec", NULL,0},
1071 /* 0x21 */ { NULL, NULL, 0 },
1072 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1073 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1074 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1075 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1076 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1077 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1078 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1079 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1080 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1081 /* 0x2b */ { "SMBecho",reply_echo,0},
1082 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1083 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1084 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1085 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1086 /* 0x30 */ { NULL, NULL, 0 },
1087 /* 0x31 */ { NULL, NULL, 0 },
1088 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1089 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1090 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1091 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1092 /* 0x36 */ { NULL, NULL, 0 },
1093 /* 0x37 */ { NULL, NULL, 0 },
1094 /* 0x38 */ { NULL, NULL, 0 },
1095 /* 0x39 */ { NULL, NULL, 0 },
1096 /* 0x3a */ { NULL, NULL, 0 },
1097 /* 0x3b */ { NULL, NULL, 0 },
1098 /* 0x3c */ { NULL, NULL, 0 },
1099 /* 0x3d */ { NULL, NULL, 0 },
1100 /* 0x3e */ { NULL, NULL, 0 },
1101 /* 0x3f */ { NULL, NULL, 0 },
1102 /* 0x40 */ { NULL, NULL, 0 },
1103 /* 0x41 */ { NULL, NULL, 0 },
1104 /* 0x42 */ { NULL, NULL, 0 },
1105 /* 0x43 */ { NULL, NULL, 0 },
1106 /* 0x44 */ { NULL, NULL, 0 },
1107 /* 0x45 */ { NULL, NULL, 0 },
1108 /* 0x46 */ { NULL, NULL, 0 },
1109 /* 0x47 */ { NULL, NULL, 0 },
1110 /* 0x48 */ { NULL, NULL, 0 },
1111 /* 0x49 */ { NULL, NULL, 0 },
1112 /* 0x4a */ { NULL, NULL, 0 },
1113 /* 0x4b */ { NULL, NULL, 0 },
1114 /* 0x4c */ { NULL, NULL, 0 },
1115 /* 0x4d */ { NULL, NULL, 0 },
1116 /* 0x4e */ { NULL, NULL, 0 },
1117 /* 0x4f */ { NULL, NULL, 0 },
1118 /* 0x50 */ { NULL, NULL, 0 },
1119 /* 0x51 */ { NULL, NULL, 0 },
1120 /* 0x52 */ { NULL, NULL, 0 },
1121 /* 0x53 */ { NULL, NULL, 0 },
1122 /* 0x54 */ { NULL, NULL, 0 },
1123 /* 0x55 */ { NULL, NULL, 0 },
1124 /* 0x56 */ { NULL, NULL, 0 },
1125 /* 0x57 */ { NULL, NULL, 0 },
1126 /* 0x58 */ { NULL, NULL, 0 },
1127 /* 0x59 */ { NULL, NULL, 0 },
1128 /* 0x5a */ { NULL, NULL, 0 },
1129 /* 0x5b */ { NULL, NULL, 0 },
1130 /* 0x5c */ { NULL, NULL, 0 },
1131 /* 0x5d */ { NULL, NULL, 0 },
1132 /* 0x5e */ { NULL, NULL, 0 },
1133 /* 0x5f */ { NULL, NULL, 0 },
1134 /* 0x60 */ { NULL, NULL, 0 },
1135 /* 0x61 */ { NULL, NULL, 0 },
1136 /* 0x62 */ { NULL, NULL, 0 },
1137 /* 0x63 */ { NULL, NULL, 0 },
1138 /* 0x64 */ { NULL, NULL, 0 },
1139 /* 0x65 */ { NULL, NULL, 0 },
1140 /* 0x66 */ { NULL, NULL, 0 },
1141 /* 0x67 */ { NULL, NULL, 0 },
1142 /* 0x68 */ { NULL, NULL, 0 },
1143 /* 0x69 */ { NULL, NULL, 0 },
1144 /* 0x6a */ { NULL, NULL, 0 },
1145 /* 0x6b */ { NULL, NULL, 0 },
1146 /* 0x6c */ { NULL, NULL, 0 },
1147 /* 0x6d */ { NULL, NULL, 0 },
1148 /* 0x6e */ { NULL, NULL, 0 },
1149 /* 0x6f */ { NULL, NULL, 0 },
1150 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1151 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1152 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1153 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1154 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1155 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1156 /* 0x76 */ { NULL, NULL, 0 },
1157 /* 0x77 */ { NULL, NULL, 0 },
1158 /* 0x78 */ { NULL, NULL, 0 },
1159 /* 0x79 */ { NULL, NULL, 0 },
1160 /* 0x7a */ { NULL, NULL, 0 },
1161 /* 0x7b */ { NULL, NULL, 0 },
1162 /* 0x7c */ { NULL, NULL, 0 },
1163 /* 0x7d */ { NULL, NULL, 0 },
1164 /* 0x7e */ { NULL, NULL, 0 },
1165 /* 0x7f */ { NULL, NULL, 0 },
1166 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1167 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1168 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1169 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1170 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1171 /* 0x85 */ { NULL, NULL, 0 },
1172 /* 0x86 */ { NULL, NULL, 0 },
1173 /* 0x87 */ { NULL, NULL, 0 },
1174 /* 0x88 */ { NULL, NULL, 0 },
1175 /* 0x89 */ { NULL, NULL, 0 },
1176 /* 0x8a */ { NULL, NULL, 0 },
1177 /* 0x8b */ { NULL, NULL, 0 },
1178 /* 0x8c */ { NULL, NULL, 0 },
1179 /* 0x8d */ { NULL, NULL, 0 },
1180 /* 0x8e */ { NULL, NULL, 0 },
1181 /* 0x8f */ { NULL, NULL, 0 },
1182 /* 0x90 */ { NULL, NULL, 0 },
1183 /* 0x91 */ { NULL, NULL, 0 },
1184 /* 0x92 */ { NULL, NULL, 0 },
1185 /* 0x93 */ { NULL, NULL, 0 },
1186 /* 0x94 */ { NULL, NULL, 0 },
1187 /* 0x95 */ { NULL, NULL, 0 },
1188 /* 0x96 */ { NULL, NULL, 0 },
1189 /* 0x97 */ { NULL, NULL, 0 },
1190 /* 0x98 */ { NULL, NULL, 0 },
1191 /* 0x99 */ { NULL, NULL, 0 },
1192 /* 0x9a */ { NULL, NULL, 0 },
1193 /* 0x9b */ { NULL, NULL, 0 },
1194 /* 0x9c */ { NULL, NULL, 0 },
1195 /* 0x9d */ { NULL, NULL, 0 },
1196 /* 0x9e */ { NULL, NULL, 0 },
1197 /* 0x9f */ { NULL, NULL, 0 },
1198 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1199 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1200 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1201 /* 0xa3 */ { NULL, NULL, 0 },
1202 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1203 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1204 /* 0xa6 */ { NULL, NULL, 0 },
1205 /* 0xa7 */ { NULL, NULL, 0 },
1206 /* 0xa8 */ { NULL, NULL, 0 },
1207 /* 0xa9 */ { NULL, NULL, 0 },
1208 /* 0xaa */ { NULL, NULL, 0 },
1209 /* 0xab */ { NULL, NULL, 0 },
1210 /* 0xac */ { NULL, NULL, 0 },
1211 /* 0xad */ { NULL, NULL, 0 },
1212 /* 0xae */ { NULL, NULL, 0 },
1213 /* 0xaf */ { NULL, NULL, 0 },
1214 /* 0xb0 */ { NULL, NULL, 0 },
1215 /* 0xb1 */ { NULL, NULL, 0 },
1216 /* 0xb2 */ { NULL, NULL, 0 },
1217 /* 0xb3 */ { NULL, NULL, 0 },
1218 /* 0xb4 */ { NULL, NULL, 0 },
1219 /* 0xb5 */ { NULL, NULL, 0 },
1220 /* 0xb6 */ { NULL, NULL, 0 },
1221 /* 0xb7 */ { NULL, NULL, 0 },
1222 /* 0xb8 */ { NULL, NULL, 0 },
1223 /* 0xb9 */ { NULL, NULL, 0 },
1224 /* 0xba */ { NULL, NULL, 0 },
1225 /* 0xbb */ { NULL, NULL, 0 },
1226 /* 0xbc */ { NULL, NULL, 0 },
1227 /* 0xbd */ { NULL, NULL, 0 },
1228 /* 0xbe */ { NULL, NULL, 0 },
1229 /* 0xbf */ { NULL, NULL, 0 },
1230 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1231 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1232 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1233 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1234 /* 0xc4 */ { NULL, NULL, 0 },
1235 /* 0xc5 */ { NULL, NULL, 0 },
1236 /* 0xc6 */ { NULL, NULL, 0 },
1237 /* 0xc7 */ { NULL, NULL, 0 },
1238 /* 0xc8 */ { NULL, NULL, 0 },
1239 /* 0xc9 */ { NULL, NULL, 0 },
1240 /* 0xca */ { NULL, NULL, 0 },
1241 /* 0xcb */ { NULL, NULL, 0 },
1242 /* 0xcc */ { NULL, NULL, 0 },
1243 /* 0xcd */ { NULL, NULL, 0 },
1244 /* 0xce */ { NULL, NULL, 0 },
1245 /* 0xcf */ { NULL, NULL, 0 },
1246 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1247 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1248 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1249 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1250 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1251 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1252 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1253 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1254 /* 0xd8 */ { NULL, NULL, 0 },
1255 /* 0xd9 */ { NULL, NULL, 0 },
1256 /* 0xda */ { NULL, NULL, 0 },
1257 /* 0xdb */ { NULL, NULL, 0 },
1258 /* 0xdc */ { NULL, NULL, 0 },
1259 /* 0xdd */ { NULL, NULL, 0 },
1260 /* 0xde */ { NULL, NULL, 0 },
1261 /* 0xdf */ { NULL, NULL, 0 },
1262 /* 0xe0 */ { NULL, NULL, 0 },
1263 /* 0xe1 */ { NULL, NULL, 0 },
1264 /* 0xe2 */ { NULL, NULL, 0 },
1265 /* 0xe3 */ { NULL, NULL, 0 },
1266 /* 0xe4 */ { NULL, NULL, 0 },
1267 /* 0xe5 */ { NULL, NULL, 0 },
1268 /* 0xe6 */ { NULL, NULL, 0 },
1269 /* 0xe7 */ { NULL, NULL, 0 },
1270 /* 0xe8 */ { NULL, NULL, 0 },
1271 /* 0xe9 */ { NULL, NULL, 0 },
1272 /* 0xea */ { NULL, NULL, 0 },
1273 /* 0xeb */ { NULL, NULL, 0 },
1274 /* 0xec */ { NULL, NULL, 0 },
1275 /* 0xed */ { NULL, NULL, 0 },
1276 /* 0xee */ { NULL, NULL, 0 },
1277 /* 0xef */ { NULL, NULL, 0 },
1278 /* 0xf0 */ { NULL, NULL, 0 },
1279 /* 0xf1 */ { NULL, NULL, 0 },
1280 /* 0xf2 */ { NULL, NULL, 0 },
1281 /* 0xf3 */ { NULL, NULL, 0 },
1282 /* 0xf4 */ { NULL, NULL, 0 },
1283 /* 0xf5 */ { NULL, NULL, 0 },
1284 /* 0xf6 */ { NULL, NULL, 0 },
1285 /* 0xf7 */ { NULL, NULL, 0 },
1286 /* 0xf8 */ { NULL, NULL, 0 },
1287 /* 0xf9 */ { NULL, NULL, 0 },
1288 /* 0xfa */ { NULL, NULL, 0 },
1289 /* 0xfb */ { NULL, NULL, 0 },
1290 /* 0xfc */ { NULL, NULL, 0 },
1291 /* 0xfd */ { NULL, NULL, 0 },
1292 /* 0xfe */ { NULL, NULL, 0 },
1293 /* 0xff */ { NULL, NULL, 0 }
1297 /*******************************************************************
1298 allocate and initialize a reply packet
1299 ********************************************************************/
1301 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1302 const char *inbuf, char **outbuf, uint8_t num_words,
1306 * Protect against integer wrap
1308 if ((num_bytes > 0xffffff)
1309 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1311 if (asprintf(&msg, "num_bytes too large: %u",
1312 (unsigned)num_bytes) == -1) {
1313 msg = CONST_DISCARD(char *, "num_bytes too large");
1318 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1319 smb_size + num_words*2 + num_bytes);
1320 if (*outbuf == NULL) {
1324 construct_reply_common(req, inbuf, *outbuf);
1325 srv_set_message(*outbuf, num_words, num_bytes, false);
1327 * Zero out the word area, the caller has to take care of the bcc area
1330 if (num_words != 0) {
1331 memset(*outbuf + smb_vwv0, 0, num_words*2);
1337 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1340 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1342 smb_panic("could not allocate output buffer\n");
1344 req->outbuf = (uint8_t *)outbuf;
1348 /*******************************************************************
1349 Dump a packet to a file.
1350 ********************************************************************/
1352 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1356 if (DEBUGLEVEL < 50) {
1360 if (len < 4) len = smb_len(data)+4;
1361 for (i=1;i<100;i++) {
1362 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1363 type ? "req" : "resp") == -1) {
1366 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1367 if (fd != -1 || errno != EEXIST) break;
1370 ssize_t ret = write(fd, data, len);
1372 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1374 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1379 /****************************************************************************
1380 Prepare everything for calling the actual request function, and potentially
1381 call the request function via the "new" interface.
1383 Return False if the "legacy" function needs to be called, everything is
1386 Return True if we're done.
1388 I know this API sucks, but it is the one with the least code change I could
1390 ****************************************************************************/
1392 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1396 connection_struct *conn = NULL;
1397 struct smbd_server_connection *sconn = smbd_server_conn;
1401 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1402 * so subtract 4 from it. */
1403 if (!valid_smb_header(req->inbuf)
1404 || (size < (smb_size - 4))) {
1405 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1406 smb_len(req->inbuf)));
1407 exit_server_cleanly("Non-SMB packet");
1410 if (smb_messages[type].fn == NULL) {
1411 DEBUG(0,("Unknown message type %d!\n",type));
1412 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1413 reply_unknown_new(req, type);
1417 flags = smb_messages[type].flags;
1419 /* In share mode security we must ignore the vuid. */
1420 session_tag = (lp_security() == SEC_SHARE)
1421 ? UID_FIELD_INVALID : req->vuid;
1424 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1425 (int)sys_getpid(), (unsigned long)conn));
1427 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1429 /* Ensure this value is replaced in the incoming packet. */
1430 SSVAL(req->inbuf,smb_uid,session_tag);
1433 * Ensure the correct username is in current_user_info. This is a
1434 * really ugly bugfix for problems with multiple session_setup_and_X's
1435 * being done and allowing %U and %G substitutions to work correctly.
1436 * There is a reason this code is done here, don't move it unless you
1437 * know what you're doing... :-).
1441 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1442 user_struct *vuser = NULL;
1444 sconn->smb1.sessions.last_session_tag = session_tag;
1445 if(session_tag != UID_FIELD_INVALID) {
1446 vuser = get_valid_user_struct(sconn, session_tag);
1448 set_current_user_info(
1449 vuser->server_info->sanitized_username,
1450 vuser->server_info->unix_name,
1451 pdb_get_domain(vuser->server_info
1457 /* Does this call need to be run as the connected user? */
1458 if (flags & AS_USER) {
1460 /* Does this call need a valid tree connection? */
1463 * Amazingly, the error code depends on the command
1466 if (type == SMBntcreateX) {
1467 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1469 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1474 if (!change_to_user(conn,session_tag)) {
1475 DEBUG(0, ("Error: Could not change to user. Removing "
1476 "deferred open, mid=%llu.\n",
1477 (unsigned long long)req->mid));
1478 reply_force_doserror(req, ERRSRV, ERRbaduid);
1482 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1484 /* Does it need write permission? */
1485 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1486 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1490 /* IPC services are limited */
1491 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1492 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1496 /* This call needs to be run as root */
1497 change_to_root_user();
1500 /* load service specific parameters */
1502 if (req->encrypted) {
1503 conn->encrypted_tid = true;
1504 /* encrypted required from now on. */
1505 conn->encrypt_level = Required;
1506 } else if (ENCRYPTION_REQUIRED(conn)) {
1507 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1508 exit_server_cleanly("encryption required "
1514 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1515 (flags & (AS_USER|DO_CHDIR)
1517 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1520 conn->num_smb_operations++;
1523 /* does this protocol need to be run as guest? */
1524 if ((flags & AS_GUEST)
1525 && (!change_to_guest() ||
1526 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1527 lp_hostsdeny(-1)))) {
1528 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 smb_messages[type].fn(req);
1536 /****************************************************************************
1537 Construct a reply to the incoming packet.
1538 ****************************************************************************/
1540 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1541 uint32_t seqnum, bool encrypted,
1542 struct smb_perfcount_data *deferred_pcd)
1544 connection_struct *conn;
1545 struct smb_request *req;
1547 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1548 smb_panic("could not allocate smb_request");
1551 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1553 exit_server_cleanly("Invalid SMB request");
1556 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1558 /* we popped this message off the queue - keep original perf data */
1560 req->pcd = *deferred_pcd;
1562 SMB_PERFCOUNT_START(&req->pcd);
1563 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1564 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1567 conn = switch_message(req->cmd, req, size);
1569 if (req->unread_bytes) {
1570 /* writeX failed. drain socket. */
1571 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1572 req->unread_bytes) {
1573 smb_panic("failed to drain pending bytes");
1575 req->unread_bytes = 0;
1583 if (req->outbuf == NULL) {
1587 if (CVAL(req->outbuf,0) == 0) {
1588 show_msg((char *)req->outbuf);
1591 if (!srv_send_smb(smbd_server_fd(),
1592 (char *)req->outbuf,
1593 true, req->seqnum+1,
1594 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1596 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1604 /****************************************************************************
1605 Process an smb from the client
1606 ****************************************************************************/
1607 static void process_smb(struct smbd_server_connection *conn,
1608 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1609 uint32_t seqnum, bool encrypted,
1610 struct smb_perfcount_data *deferred_pcd)
1612 int msg_type = CVAL(inbuf,0);
1614 DO_PROFILE_INC(smb_count);
1616 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1618 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1620 (unsigned int)unread_bytes ));
1622 if (msg_type != 0) {
1624 * NetBIOS session request, keepalive, etc.
1626 reply_special((char *)inbuf);
1630 if (smbd_server_conn->allow_smb2) {
1631 if (smbd_is_smb2_header(inbuf, nread)) {
1632 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1635 smbd_server_conn->allow_smb2 = false;
1638 show_msg((char *)inbuf);
1640 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1644 conn->smb1.num_requests++;
1646 /* The timeout_processing function isn't run nearly
1647 often enough to implement 'max log size' without
1648 overrunning the size of the file by many megabytes.
1649 This is especially true if we are running at debug
1650 level 10. Checking every 50 SMBs is a nice
1651 tradeoff of performance vs log file size overrun. */
1653 if ((conn->smb1.num_requests % 50) == 0 &&
1654 need_to_check_log_size()) {
1655 change_to_root_user();
1660 /****************************************************************************
1661 Return a string containing the function name of a SMB command.
1662 ****************************************************************************/
1664 const char *smb_fn_name(int type)
1666 const char *unknown_name = "SMBunknown";
1668 if (smb_messages[type].name == NULL)
1669 return(unknown_name);
1671 return(smb_messages[type].name);
1674 /****************************************************************************
1675 Helper functions for contruct_reply.
1676 ****************************************************************************/
1678 void add_to_common_flags2(uint32 v)
1683 void remove_from_common_flags2(uint32 v)
1685 common_flags2 &= ~v;
1688 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1691 srv_set_message(outbuf,0,0,false);
1693 SCVAL(outbuf, smb_com, req->cmd);
1694 SIVAL(outbuf,smb_rcls,0);
1695 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1696 SSVAL(outbuf,smb_flg2,
1697 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1699 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1701 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1702 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1703 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1704 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1707 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1709 construct_reply_common(req, (char *)req->inbuf, outbuf);
1713 * How many bytes have we already accumulated up to the current wct field
1717 size_t req_wct_ofs(struct smb_request *req)
1721 if (req->chain_outbuf == NULL) {
1724 buf_size = talloc_get_size(req->chain_outbuf);
1725 if ((buf_size % 4) != 0) {
1726 buf_size += (4 - (buf_size % 4));
1728 return buf_size - 4;
1732 * Hack around reply_nterror & friends not being aware of chained requests,
1733 * generating illegal (i.e. wct==0) chain replies.
1736 static void fixup_chain_error_packet(struct smb_request *req)
1738 uint8_t *outbuf = req->outbuf;
1740 reply_outbuf(req, 2, 0);
1741 memcpy(req->outbuf, outbuf, smb_wct);
1742 TALLOC_FREE(outbuf);
1743 SCVAL(req->outbuf, smb_vwv0, 0xff);
1747 * @brief Find the smb_cmd offset of the last command pushed
1748 * @param[in] buf The buffer we're building up
1749 * @retval Where can we put our next andx cmd?
1751 * While chaining requests, the "next" request we're looking at needs to put
1752 * its SMB_Command before the data the previous request already built up added
1753 * to the chain. Find the offset to the place where we have to put our cmd.
1756 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1761 cmd = CVAL(buf, smb_com);
1763 SMB_ASSERT(is_andx_req(cmd));
1767 while (CVAL(buf, ofs) != 0xff) {
1769 if (!is_andx_req(CVAL(buf, ofs))) {
1774 * ofs is from start of smb header, so add the 4 length
1775 * bytes. The next cmd is right after the wct field.
1777 ofs = SVAL(buf, ofs+2) + 4 + 1;
1779 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1787 * @brief Do the smb chaining at a buffer level
1788 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1789 * @param[in] smb_command The command that we want to issue
1790 * @param[in] wct How many words?
1791 * @param[in] vwv The words, already in network order
1792 * @param[in] bytes_alignment How shall we align "bytes"?
1793 * @param[in] num_bytes How many bytes?
1794 * @param[in] bytes The data the request ships
1796 * smb_splice_chain() adds the vwv and bytes to the request already present in
1800 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1801 uint8_t wct, const uint16_t *vwv,
1802 size_t bytes_alignment,
1803 uint32_t num_bytes, const uint8_t *bytes)
1806 size_t old_size, new_size;
1808 size_t chain_padding = 0;
1809 size_t bytes_padding = 0;
1812 old_size = talloc_get_size(*poutbuf);
1815 * old_size == smb_wct means we're pushing the first request in for
1819 first_request = (old_size == smb_wct);
1821 if (!first_request && ((old_size % 4) != 0)) {
1823 * Align the wct field of subsequent requests to a 4-byte
1826 chain_padding = 4 - (old_size % 4);
1830 * After the old request comes the new wct field (1 byte), the vwv's
1831 * and the num_bytes field. After at we might need to align the bytes
1832 * given to us to "bytes_alignment", increasing the num_bytes value.
1835 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1837 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1838 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1841 new_size += bytes_padding + num_bytes;
1843 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1844 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1845 (unsigned)new_size));
1849 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1850 if (outbuf == NULL) {
1851 DEBUG(0, ("talloc failed\n"));
1856 if (first_request) {
1857 SCVAL(outbuf, smb_com, smb_command);
1859 size_t andx_cmd_ofs;
1861 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1862 DEBUG(1, ("invalid command chain\n"));
1863 *poutbuf = TALLOC_REALLOC_ARRAY(
1864 NULL, *poutbuf, uint8_t, old_size);
1868 if (chain_padding != 0) {
1869 memset(outbuf + old_size, 0, chain_padding);
1870 old_size += chain_padding;
1873 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1874 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1880 * Push the chained request:
1885 SCVAL(outbuf, ofs, wct);
1892 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1893 ofs += sizeof(uint16_t) * wct;
1899 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1900 ofs += sizeof(uint16_t);
1906 if (bytes_padding != 0) {
1907 memset(outbuf + ofs, 0, bytes_padding);
1908 ofs += bytes_padding;
1915 memcpy(outbuf + ofs, bytes, num_bytes);
1920 /****************************************************************************
1921 Construct a chained reply and add it to the already made reply
1922 ****************************************************************************/
1924 void chain_reply(struct smb_request *req)
1926 size_t smblen = smb_len(req->inbuf);
1927 size_t already_used, length_needed;
1929 uint32_t chain_offset; /* uint32_t to avoid overflow */
1936 if (IVAL(req->outbuf, smb_rcls) != 0) {
1937 fixup_chain_error_packet(req);
1941 * Any of the AndX requests and replies have at least a wct of
1942 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1943 * beginning of the SMB header to the next wct field.
1945 * None of the AndX requests put anything valuable in vwv[0] and [1],
1946 * so we can overwrite it here to form the chain.
1949 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1950 if (req->chain_outbuf == NULL) {
1951 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1952 req, req->outbuf, uint8_t,
1953 smb_len(req->outbuf) + 4);
1954 if (req->chain_outbuf == NULL) {
1955 smb_panic("talloc failed");
1963 * Here we assume that this is the end of the chain. For that we need
1964 * to set "next command" to 0xff and the offset to 0. If we later find
1965 * more commands in the chain, this will be overwritten again.
1968 SCVAL(req->outbuf, smb_vwv0, 0xff);
1969 SCVAL(req->outbuf, smb_vwv0+1, 0);
1970 SSVAL(req->outbuf, smb_vwv1, 0);
1972 if (req->chain_outbuf == NULL) {
1974 * In req->chain_outbuf we collect all the replies. Start the
1975 * chain by copying in the first reply.
1977 * We do the realloc because later on we depend on
1978 * talloc_get_size to determine the length of
1979 * chain_outbuf. The reply_xxx routines might have
1980 * over-allocated (reply_pipe_read_and_X used to be such an
1983 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1984 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1985 if (req->chain_outbuf == NULL) {
1986 smb_panic("talloc failed");
1991 * Update smb headers where subsequent chained commands
1992 * may have updated them.
1994 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1995 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1997 if (!smb_splice_chain(&req->chain_outbuf,
1998 CVAL(req->outbuf, smb_com),
1999 CVAL(req->outbuf, smb_wct),
2000 (uint16_t *)(req->outbuf + smb_vwv),
2001 0, smb_buflen(req->outbuf),
2002 (uint8_t *)smb_buf(req->outbuf))) {
2005 TALLOC_FREE(req->outbuf);
2009 * We use the old request's vwv field to grab the next chained command
2010 * and offset into the chained fields.
2013 chain_cmd = CVAL(req->vwv+0, 0);
2014 chain_offset = SVAL(req->vwv+1, 0);
2016 if (chain_cmd == 0xff) {
2018 * End of chain, no more requests from the client. So ship the
2021 smb_setlen((char *)(req->chain_outbuf),
2022 talloc_get_size(req->chain_outbuf) - 4);
2024 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2025 true, req->seqnum+1,
2026 IS_CONN_ENCRYPTED(req->conn)
2029 exit_server_cleanly("chain_reply: srv_send_smb "
2032 TALLOC_FREE(req->chain_outbuf);
2037 /* add a new perfcounter for this element of chain */
2038 SMB_PERFCOUNT_ADD(&req->pcd);
2039 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2040 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2043 * Check if the client tries to fool us. The request so far uses the
2044 * space to the end of the byte buffer in the request just
2045 * processed. The chain_offset can't point into that area. If that was
2046 * the case, we could end up with an endless processing of the chain,
2047 * we would always handle the same request.
2050 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2051 if (chain_offset < already_used) {
2056 * Next check: Make sure the chain offset does not point beyond the
2057 * overall smb request length.
2060 length_needed = chain_offset+1; /* wct */
2061 if (length_needed > smblen) {
2066 * Now comes the pointer magic. Goal here is to set up req->vwv and
2067 * req->buf correctly again to be able to call the subsequent
2068 * switch_message(). The chain offset (the former vwv[1]) points at
2069 * the new wct field.
2072 wct = CVAL(smb_base(req->inbuf), chain_offset);
2075 * Next consistency check: Make the new vwv array fits in the overall
2079 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2080 if (length_needed > smblen) {
2083 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2086 * Now grab the new byte buffer....
2089 buflen = SVAL(vwv+wct, 0);
2092 * .. and check that it fits.
2095 length_needed += buflen;
2096 if (length_needed > smblen) {
2099 buf = (uint8_t *)(vwv+wct+1);
2101 req->cmd = chain_cmd;
2104 req->buflen = buflen;
2107 switch_message(chain_cmd, req, smblen);
2109 if (req->outbuf == NULL) {
2111 * This happens if the chained command has suspended itself or
2112 * if it has called srv_send_smb() itself.
2118 * We end up here if the chained command was not itself chained or
2119 * suspended, but for example a close() command. We now need to splice
2120 * the chained commands' outbuf into the already built up chain_outbuf
2121 * and ship the result.
2127 * We end up here if there's any error in the chain syntax. Report a
2128 * DOS error, just like Windows does.
2130 reply_force_doserror(req, ERRSRV, ERRerror);
2131 fixup_chain_error_packet(req);
2135 * This scary statement intends to set the
2136 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2137 * to the value req->outbuf carries
2139 SSVAL(req->chain_outbuf, smb_flg2,
2140 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2141 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2144 * Transfer the error codes from the subrequest to the main one
2146 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2147 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2149 if (!smb_splice_chain(&req->chain_outbuf,
2150 CVAL(req->outbuf, smb_com),
2151 CVAL(req->outbuf, smb_wct),
2152 (uint16_t *)(req->outbuf + smb_vwv),
2153 0, smb_buflen(req->outbuf),
2154 (uint8_t *)smb_buf(req->outbuf))) {
2155 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2157 TALLOC_FREE(req->outbuf);
2159 smb_setlen((char *)(req->chain_outbuf),
2160 talloc_get_size(req->chain_outbuf) - 4);
2162 show_msg((char *)(req->chain_outbuf));
2164 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2165 true, req->seqnum+1,
2166 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2168 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2170 TALLOC_FREE(req->chain_outbuf);
2174 /****************************************************************************
2175 Check if services need reloading.
2176 ****************************************************************************/
2178 void check_reload(time_t t)
2180 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2182 if(last_smb_conf_reload_time == 0) {
2183 last_smb_conf_reload_time = t;
2184 /* Our printing subsystem might not be ready at smbd start up.
2185 Then no printer is available till the first printers check
2186 is performed. A lower initial interval circumvents this. */
2187 if ( printcap_cache_time > 60 )
2188 last_printer_reload_time = t - printcap_cache_time + 60;
2190 last_printer_reload_time = t;
2193 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2194 /* randomize over 60 second the printcap reload to avoid all
2195 * process hitting cupsd at the same time */
2196 int time_range = 60;
2198 last_printer_reload_time += random() % time_range;
2202 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2203 reload_services(True);
2204 last_smb_conf_reload_time = t;
2207 /* 'printcap cache time = 0' disable the feature */
2209 if ( printcap_cache_time != 0 )
2211 /* see if it's time to reload or if the clock has been set back */
2213 if ( (t >= last_printer_reload_time+printcap_cache_time)
2214 || (t-last_printer_reload_time < 0) )
2216 DEBUG( 3,( "Printcap cache time expired.\n"));
2218 last_printer_reload_time = t;
2223 static bool fd_is_readable(int fd)
2226 struct timeval timeout = {0, };
2232 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2236 return FD_ISSET(fd, &fds);
2239 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2241 /* TODO: make write nonblocking */
2244 static void smbd_server_connection_read_handler(
2245 struct smbd_server_connection *conn, int fd)
2247 uint8_t *inbuf = NULL;
2248 size_t inbuf_len = 0;
2249 size_t unread_bytes = 0;
2250 bool encrypted = false;
2251 TALLOC_CTX *mem_ctx = talloc_tos();
2255 bool from_client = (smbd_server_fd() == fd)?true:false;
2258 smbd_lock_socket(conn);
2260 if (!fd_is_readable(smbd_server_fd())) {
2261 DEBUG(10,("the echo listener was faster\n"));
2262 smbd_unlock_socket(conn);
2266 /* TODO: make this completely nonblocking */
2267 status = receive_smb_talloc(mem_ctx, fd,
2268 (char **)(void *)&inbuf,
2272 &inbuf_len, &seqnum,
2273 false /* trusted channel */);
2274 smbd_unlock_socket(conn);
2276 /* TODO: make this completely nonblocking */
2277 status = receive_smb_talloc(mem_ctx, fd,
2278 (char **)(void *)&inbuf,
2282 &inbuf_len, &seqnum,
2283 true /* trusted channel */);
2286 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2289 if (NT_STATUS_IS_ERR(status)) {
2290 exit_server_cleanly("failed to receive smb request");
2292 if (!NT_STATUS_IS_OK(status)) {
2297 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2298 seqnum, encrypted, NULL);
2301 static void smbd_server_connection_handler(struct event_context *ev,
2302 struct fd_event *fde,
2306 struct smbd_server_connection *conn = talloc_get_type(private_data,
2307 struct smbd_server_connection);
2309 if (flags & EVENT_FD_WRITE) {
2310 smbd_server_connection_write_handler(conn);
2311 } else if (flags & EVENT_FD_READ) {
2312 smbd_server_connection_read_handler(conn, smbd_server_fd());
2316 static void smbd_server_echo_handler(struct event_context *ev,
2317 struct fd_event *fde,
2321 struct smbd_server_connection *conn = talloc_get_type(private_data,
2322 struct smbd_server_connection);
2324 if (flags & EVENT_FD_WRITE) {
2325 smbd_server_connection_write_handler(conn);
2326 } else if (flags & EVENT_FD_READ) {
2327 smbd_server_connection_read_handler(
2328 conn, conn->smb1.echo_handler.trusted_fd);
2332 /****************************************************************************
2333 received when we should release a specific IP
2334 ****************************************************************************/
2335 static void release_ip(const char *ip, void *priv)
2337 char addr[INET6_ADDRSTRLEN];
2340 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2342 if (strncmp("::ffff:", addr, 7) == 0) {
2346 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2347 /* we can't afford to do a clean exit - that involves
2348 database writes, which would potentially mean we
2349 are still running after the failover has finished -
2350 we have to get rid of this process ID straight
2352 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2354 /* note we must exit with non-zero status so the unclean handler gets
2355 called in the parent, so that the brl database is tickled */
2360 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2361 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2363 release_ip((char *)data->data, NULL);
2366 #ifdef CLUSTER_SUPPORT
2367 static int client_get_tcp_info(struct sockaddr_storage *server,
2368 struct sockaddr_storage *client)
2371 if (server_fd == -1) {
2374 length = sizeof(*server);
2375 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2378 length = sizeof(*client);
2379 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2387 * Send keepalive packets to our client
2389 static bool keepalive_fn(const struct timeval *now, void *private_data)
2393 smbd_lock_socket(smbd_server_conn);
2394 ret = send_keepalive(smbd_server_fd());
2395 smbd_unlock_socket(smbd_server_conn);
2398 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2405 * Do the recurring check if we're idle
2407 static bool deadtime_fn(const struct timeval *now, void *private_data)
2409 struct smbd_server_connection *sconn = smbd_server_conn;
2411 if (sconn->allow_smb2) {
2412 /* TODO: implement real idle check */
2413 if (sconn->smb2.sessions.list) {
2416 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2417 messaging_send(smbd_messaging_context(), procid_self(),
2418 MSG_SHUTDOWN, &data_blob_null);
2422 if ((conn_num_open(sconn) == 0)
2423 || (conn_idle_all(sconn, now->tv_sec))) {
2424 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2425 messaging_send(smbd_messaging_context(), procid_self(),
2426 MSG_SHUTDOWN, &data_blob_null);
2434 * Do the recurring log file and smb.conf reload checks.
2437 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2439 change_to_root_user();
2441 /* update printer queue caches if necessary */
2442 update_monitored_printq_cache();
2444 /* check if we need to reload services */
2445 check_reload(time(NULL));
2447 /* Change machine password if neccessary. */
2448 attempt_machine_password_change();
2451 * Force a log file check.
2453 force_check_log_size();
2458 static int create_unlink_tmp(const char *dir)
2463 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2464 if (fname == NULL) {
2468 fd = mkstemp(fname);
2473 if (unlink(fname) == -1) {
2474 int sys_errno = errno;
2484 struct smbd_echo_state {
2485 struct tevent_context *ev;
2486 struct iovec *pending;
2487 struct smbd_server_connection *sconn;
2490 struct tevent_fd *parent_fde;
2492 struct tevent_fd *read_fde;
2493 struct tevent_req *write_req;
2496 static void smbd_echo_writer_done(struct tevent_req *req);
2498 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2502 if (state->write_req != NULL) {
2506 num_pending = talloc_array_length(state->pending);
2507 if (num_pending == 0) {
2511 state->write_req = writev_send(state, state->ev, NULL,
2512 state->parent_pipe, false,
2513 state->pending, num_pending);
2514 if (state->write_req == NULL) {
2515 DEBUG(1, ("writev_send failed\n"));
2519 talloc_steal(state->write_req, state->pending);
2520 state->pending = NULL;
2522 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2526 static void smbd_echo_writer_done(struct tevent_req *req)
2528 struct smbd_echo_state *state = tevent_req_callback_data(
2529 req, struct smbd_echo_state);
2533 written = writev_recv(req, &err);
2535 state->write_req = NULL;
2536 if (written == -1) {
2537 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2540 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2541 smbd_echo_activate_writer(state);
2544 static bool smbd_echo_reply(int fd,
2545 uint8_t *inbuf, size_t inbuf_len,
2548 struct smb_request req;
2549 uint16_t num_replies;
2554 if (inbuf_len < smb_size) {
2555 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2558 if (!valid_smb_header(inbuf)) {
2559 DEBUG(10, ("Got invalid SMB header\n"));
2563 if (!init_smb_request(&req, inbuf, 0, false, seqnum)) {
2568 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2569 smb_messages[req.cmd].name
2570 ? smb_messages[req.cmd].name : "unknown"));
2572 if (req.cmd != SMBecho) {
2579 num_replies = SVAL(req.vwv+0, 0);
2580 if (num_replies != 1) {
2581 /* Not a Windows "Hey, you're still there?" request */
2585 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2587 DEBUG(10, ("create_outbuf failed\n"));
2590 req.outbuf = (uint8_t *)outbuf;
2592 SSVAL(req.outbuf, smb_vwv0, num_replies);
2594 if (req.buflen > 0) {
2595 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2598 out_len = smb_len(req.outbuf) + 4;
2600 ok = srv_send_smb(smbd_server_fd(),
2604 TALLOC_FREE(outbuf);
2612 static void smbd_echo_exit(struct tevent_context *ev,
2613 struct tevent_fd *fde, uint16_t flags,
2616 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2620 static void smbd_echo_reader(struct tevent_context *ev,
2621 struct tevent_fd *fde, uint16_t flags,
2624 struct smbd_echo_state *state = talloc_get_type_abort(
2625 private_data, struct smbd_echo_state);
2626 struct smbd_server_connection *sconn = state->sconn;
2627 size_t unread, num_pending;
2630 uint32_t seqnum = 0;
2633 bool encrypted = false;
2635 ok = smbd_lock_socket_internal(sconn);
2637 DEBUG(0, ("%s: failed to lock socket\n",
2642 if (!fd_is_readable(smbd_server_fd())) {
2643 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2644 (int)sys_getpid()));
2645 ok = smbd_unlock_socket_internal(sconn);
2647 DEBUG(1, ("%s: failed to unlock socket in\n",
2654 num_pending = talloc_array_length(state->pending);
2655 tmp = talloc_realloc(state, state->pending, struct iovec,
2658 DEBUG(1, ("talloc_realloc failed\n"));
2661 state->pending = tmp;
2663 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2665 status = receive_smb_talloc(state, smbd_server_fd(),
2666 (char **)(void *)&state->pending[num_pending].iov_base,
2670 &state->pending[num_pending].iov_len,
2672 false /* trusted_channel*/);
2673 if (!NT_STATUS_IS_OK(status)) {
2674 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2675 (int)sys_getpid(), nt_errstr(status)));
2679 ok = smbd_unlock_socket_internal(sconn);
2681 DEBUG(1, ("%s: failed to unlock socket in\n",
2687 * place the seqnum in the packet so that the main process can reply
2690 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2691 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2693 reply = smbd_echo_reply(smbd_server_fd(),
2694 (uint8_t *)state->pending[num_pending].iov_base,
2695 state->pending[num_pending].iov_len,
2698 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2699 /* no check, shrinking by some bytes does not fail */
2700 state->pending = talloc_realloc(state, state->pending,
2704 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2705 smbd_echo_activate_writer(state);
2709 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2712 struct smbd_echo_state *state;
2714 state = talloc_zero(sconn, struct smbd_echo_state);
2715 if (state == NULL) {
2716 DEBUG(1, ("talloc failed\n"));
2719 state->sconn = sconn;
2720 state->parent_pipe = parent_pipe;
2721 state->ev = s3_tevent_context_init(state);
2722 if (state->ev == NULL) {
2723 DEBUG(1, ("tevent_context_init failed\n"));
2727 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2728 TEVENT_FD_READ, smbd_echo_exit,
2730 if (state->parent_fde == NULL) {
2731 DEBUG(1, ("tevent_add_fd failed\n"));
2735 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2736 TEVENT_FD_READ, smbd_echo_reader,
2738 if (state->read_fde == NULL) {
2739 DEBUG(1, ("tevent_add_fd failed\n"));
2745 if (tevent_loop_once(state->ev) == -1) {
2746 DEBUG(1, ("tevent_loop_once failed: %s\n",
2755 * Handle SMBecho requests in a forked child process
2757 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2759 int listener_pipe[2];
2763 res = pipe(listener_pipe);
2765 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2768 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2769 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2770 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2778 close(listener_pipe[0]);
2780 status = reinit_after_fork(smbd_messaging_context(),
2781 smbd_event_context(), false);
2782 if (!NT_STATUS_IS_OK(status)) {
2783 DEBUG(1, ("reinit_after_fork failed: %s\n",
2784 nt_errstr(status)));
2787 smbd_echo_loop(sconn, listener_pipe[1]);
2790 close(listener_pipe[1]);
2791 listener_pipe[1] = -1;
2792 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2794 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2797 * Without smb signing this is the same as the normal smbd
2798 * listener. This needs to change once signing comes in.
2800 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2802 sconn->smb1.echo_handler.trusted_fd,
2804 smbd_server_echo_handler,
2806 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2807 DEBUG(1, ("event_add_fd failed\n"));
2814 if (listener_pipe[0] != -1) {
2815 close(listener_pipe[0]);
2817 if (listener_pipe[1] != -1) {
2818 close(listener_pipe[1]);
2820 sconn->smb1.echo_handler.trusted_fd = -1;
2821 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2822 close(sconn->smb1.echo_handler.socket_lock_fd);
2824 sconn->smb1.echo_handler.trusted_fd = -1;
2825 sconn->smb1.echo_handler.socket_lock_fd = -1;
2829 /****************************************************************************
2830 Process commands from the client
2831 ****************************************************************************/
2833 void smbd_process(void)
2835 TALLOC_CTX *frame = talloc_stackframe();
2836 char remaddr[INET6_ADDRSTRLEN];
2838 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2839 lp_security() != SEC_SHARE &&
2840 !lp_async_smb_echo_handler()) {
2841 smbd_server_conn->allow_smb2 = true;
2844 /* Ensure child is set to blocking mode */
2845 set_blocking(smbd_server_fd(),True);
2847 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2848 set_socket_options(smbd_server_fd(), lp_socket_options());
2850 /* this is needed so that we get decent entries
2851 in smbstatus for port 445 connects */
2852 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2856 reload_services(true);
2859 * Before the first packet, check the global hosts allow/ hosts deny
2860 * parameters before doing any parsing of packets passed to us by the
2861 * client. This prevents attacks on our parsing code from hosts not in
2862 * the hosts allow list.
2865 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2866 lp_hostsdeny(-1))) {
2867 char addr[INET6_ADDRSTRLEN];
2870 * send a negative session response "not listening on calling
2873 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2874 DEBUG( 1, ("Connection denied from %s\n",
2875 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2876 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2878 exit_server_cleanly("connection denied");
2885 smb_perfcount_init();
2887 if (!init_account_policy()) {
2888 exit_server("Could not open account policy tdb.\n");
2891 if (*lp_rootdir()) {
2892 if (chroot(lp_rootdir()) != 0) {
2893 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2894 exit_server("Failed to chroot()");
2896 if (chdir("/") == -1) {
2897 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2898 exit_server("Failed to chroot()");
2900 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2903 if (!srv_init_signing(smbd_server_conn)) {
2904 exit_server("Failed to init smb_signing");
2907 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2908 exit_server("Failed to fork echo handler");
2912 if (!init_oplocks(smbd_messaging_context()))
2913 exit_server("Failed to init oplocks");
2915 /* register our message handlers */
2916 messaging_register(smbd_messaging_context(), NULL,
2917 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2918 messaging_register(smbd_messaging_context(), NULL,
2919 MSG_SMB_RELEASE_IP, msg_release_ip);
2920 messaging_register(smbd_messaging_context(), NULL,
2921 MSG_SMB_CLOSE_FILE, msg_close_file);
2924 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2925 * MSGs to all child processes
2927 messaging_deregister(smbd_messaging_context(),
2929 messaging_register(smbd_messaging_context(), NULL,
2930 MSG_DEBUG, debug_message);
2932 if ((lp_keepalive() != 0)
2933 && !(event_add_idle(smbd_event_context(), NULL,
2934 timeval_set(lp_keepalive(), 0),
2935 "keepalive", keepalive_fn,
2937 DEBUG(0, ("Could not add keepalive event\n"));
2941 if (!(event_add_idle(smbd_event_context(), NULL,
2942 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2943 "deadtime", deadtime_fn, NULL))) {
2944 DEBUG(0, ("Could not add deadtime event\n"));
2948 if (!(event_add_idle(smbd_event_context(), NULL,
2949 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2950 "housekeeping", housekeeping_fn, NULL))) {
2951 DEBUG(0, ("Could not add housekeeping event\n"));
2955 #ifdef CLUSTER_SUPPORT
2957 if (lp_clustering()) {
2959 * We need to tell ctdb about our client's TCP
2960 * connection, so that for failover ctdbd can send
2961 * tickle acks, triggering a reconnection by the
2965 struct sockaddr_storage srv, clnt;
2967 if (client_get_tcp_info(&srv, &clnt) == 0) {
2971 status = ctdbd_register_ips(
2972 messaging_ctdbd_connection(),
2973 &srv, &clnt, release_ip, NULL);
2975 if (!NT_STATUS_IS_OK(status)) {
2976 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2977 nt_errstr(status)));
2981 DEBUG(0,("Unable to get tcp info for "
2982 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2989 smbd_server_conn->nbt.got_session = false;
2991 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2993 smbd_server_conn->smb1.sessions.done_sesssetup = false;
2994 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
2995 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
2996 /* users from session setup */
2997 smbd_server_conn->smb1.sessions.session_userlist = NULL;
2998 /* workgroup from session setup. */
2999 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
3000 /* this holds info on user ids that are already validated for this VC */
3001 smbd_server_conn->smb1.sessions.validated_users = NULL;
3002 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
3003 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
3004 #ifdef HAVE_NETGROUP
3005 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
3008 conn_init(smbd_server_conn);
3009 if (!init_dptrs(smbd_server_conn)) {
3010 exit_server("init_dptrs() failed");
3013 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
3017 smbd_server_connection_handler,
3019 if (!smbd_server_conn->smb1.fde) {
3020 exit_server("failed to create smbd_server_connection fde");
3028 frame = talloc_stackframe_pool(8192);
3032 status = smbd_server_connection_loop_once(smbd_server_conn);
3033 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3034 !NT_STATUS_IS_OK(status)) {
3035 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3036 " exiting\n", nt_errstr(status)));
3043 exit_server_cleanly(NULL);
3046 bool req_is_in_chain(struct smb_request *req)
3048 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3050 * We're right now handling a subsequent request, so we must
3056 if (!is_andx_req(req->cmd)) {
3062 * Okay, an illegal request, but definitely not chained :-)
3067 return (CVAL(req->vwv+0, 0) != 0xFF);