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"
37 #include "librpc/gen_ndr/messaging.h"
39 extern bool global_machine_password_needs_changing;
41 static void construct_reply_common(struct smb_request *req, const char *inbuf,
43 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
45 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
49 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
53 smbd_server_conn->smb1.echo_handler.ref_count++;
55 if (smbd_server_conn->smb1.echo_handler.ref_count > 1) {
59 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
61 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
62 SMB_F_SETLKW, 0, 0, F_WRLCK);
67 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
72 void smbd_lock_socket(struct smbd_server_connection *sconn)
74 if (!smbd_lock_socket_internal(sconn)) {
75 exit_server_cleanly("failed to lock socket");
79 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
83 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
87 smbd_server_conn->smb1.echo_handler.ref_count--;
89 if (smbd_server_conn->smb1.echo_handler.ref_count > 0) {
93 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
94 SMB_F_SETLKW, 0, 0, F_UNLCK);
99 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
104 void smbd_unlock_socket(struct smbd_server_connection *sconn)
106 if (!smbd_unlock_socket_internal(sconn)) {
107 exit_server_cleanly("failed to unlock socket");
111 /* Accessor function for smb_read_error for smbd functions. */
113 /****************************************************************************
115 ****************************************************************************/
117 bool srv_send_smb(int fd, char *buffer,
118 bool do_signing, uint32_t seqnum,
120 struct smb_perfcount_data *pcd)
125 char *buf_out = buffer;
127 smbd_lock_socket(smbd_server_conn);
130 /* Sign the outgoing packet if required. */
131 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
135 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
136 if (!NT_STATUS_IS_OK(status)) {
137 DEBUG(0, ("send_smb: SMB encryption failed "
138 "on outgoing packet! Error %s\n",
139 nt_errstr(status) ));
144 len = smb_len(buf_out) + 4;
146 ret = write_data(fd,buf_out+nwritten,len - nwritten);
148 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
149 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
150 srv_free_enc_buffer(buf_out);
154 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
155 srv_free_enc_buffer(buf_out);
157 SMB_PERFCOUNT_END(pcd);
159 smbd_unlock_socket(smbd_server_conn);
163 /*******************************************************************
164 Setup the word count and byte count for a smb message.
165 ********************************************************************/
167 int srv_set_message(char *buf,
172 if (zero && (num_words || num_bytes)) {
173 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
175 SCVAL(buf,smb_wct,num_words);
176 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
177 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
178 return (smb_size + num_words*2 + num_bytes);
181 static bool valid_smb_header(const uint8_t *inbuf)
183 if (is_encrypted_packet(inbuf)) {
187 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
188 * but it just looks weird to call strncmp for this one.
190 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
193 /* Socket functions for smbd packet processing. */
195 static bool valid_packet_size(size_t len)
198 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
199 * of header. Don't print the error if this fits.... JRA.
202 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
203 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
204 (unsigned long)len));
210 static NTSTATUS read_packet_remainder(int fd, char *buffer,
211 unsigned int timeout, ssize_t len)
217 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
220 /****************************************************************************
221 Attempt a zerocopy writeX read. We know here that len > smb_size-4
222 ****************************************************************************/
225 * Unfortunately, earlier versions of smbclient/libsmbclient
226 * don't send this "standard" writeX header. I've fixed this
227 * for 3.2 but we'll use the old method with earlier versions.
228 * Windows and CIFSFS at least use this standard size. Not
232 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
233 (2*14) + /* word count (including bcc) */ \
236 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
237 const char lenbuf[4],
238 int fd, char **buffer,
239 unsigned int timeout,
243 /* Size of a WRITEX call (+4 byte len). */
244 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
245 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
249 memcpy(writeX_header, lenbuf, 4);
251 status = read_fd_with_timeout(
252 fd, writeX_header + 4,
253 STANDARD_WRITE_AND_X_HEADER_SIZE,
254 STANDARD_WRITE_AND_X_HEADER_SIZE,
257 if (!NT_STATUS_IS_OK(status)) {
262 * Ok - now try and see if this is a possible
266 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
268 * If the data offset is beyond what
269 * we've read, drain the extra bytes.
271 uint16_t doff = SVAL(writeX_header,smb_vwv11);
274 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
275 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
276 if (drain_socket(smbd_server_fd(), drain) != drain) {
277 smb_panic("receive_smb_raw_talloc_partial_read:"
278 " failed to drain pending bytes");
281 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
284 /* Spoof down the length and null out the bcc. */
285 set_message_bcc(writeX_header, 0);
286 newlen = smb_len(writeX_header);
288 /* Copy the header we've written. */
290 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
292 sizeof(writeX_header));
294 if (*buffer == NULL) {
295 DEBUG(0, ("Could not allocate inbuf of length %d\n",
296 (int)sizeof(writeX_header)));
297 return NT_STATUS_NO_MEMORY;
300 /* Work out the remaining bytes. */
301 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
302 *len_ret = newlen + 4;
306 if (!valid_packet_size(len)) {
307 return NT_STATUS_INVALID_PARAMETER;
311 * Not a valid writeX call. Just do the standard
315 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
317 if (*buffer == NULL) {
318 DEBUG(0, ("Could not allocate inbuf of length %d\n",
320 return NT_STATUS_NO_MEMORY;
323 /* Copy in what we already read. */
326 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
327 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
330 status = read_packet_remainder(
331 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
334 if (!NT_STATUS_IS_OK(status)) {
335 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
345 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
346 char **buffer, unsigned int timeout,
347 size_t *p_unread, size_t *plen)
351 int min_recv_size = lp_min_receive_file_size();
356 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
357 if (!NT_STATUS_IS_OK(status)) {
358 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
362 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
363 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
364 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
365 !srv_is_signing_active(smbd_server_conn) &&
366 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
368 return receive_smb_raw_talloc_partial_read(
369 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
372 if (!valid_packet_size(len)) {
373 return NT_STATUS_INVALID_PARAMETER;
377 * The +4 here can't wrap, we've checked the length above already.
380 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
382 if (*buffer == NULL) {
383 DEBUG(0, ("Could not allocate inbuf of length %d\n",
385 return NT_STATUS_NO_MEMORY;
388 memcpy(*buffer, lenbuf, sizeof(lenbuf));
390 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
391 if (!NT_STATUS_IS_OK(status)) {
399 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
400 char **buffer, unsigned int timeout,
401 size_t *p_unread, bool *p_encrypted,
404 bool trusted_channel)
409 *p_encrypted = false;
411 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
413 if (!NT_STATUS_IS_OK(status)) {
417 if (is_encrypted_packet((uint8_t *)*buffer)) {
418 status = srv_decrypt_buffer(*buffer);
419 if (!NT_STATUS_IS_OK(status)) {
420 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
421 "incoming packet! Error %s\n",
422 nt_errstr(status) ));
428 /* Check the incoming SMB signature. */
429 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
430 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
431 "incoming packet!\n"));
432 return NT_STATUS_INVALID_NETWORK_RESPONSE;
440 * Initialize a struct smb_request from an inbuf
443 static bool init_smb_request(struct smb_request *req, const uint8 *inbuf,
444 size_t unread_bytes, bool encrypted,
447 struct smbd_server_connection *sconn = smbd_server_conn;
448 size_t req_size = smb_len(inbuf) + 4;
449 /* Ensure we have at least smb_size bytes. */
450 if (req_size < smb_size) {
451 DEBUG(0,("init_smb_request: invalid request size %u\n",
452 (unsigned int)req_size ));
455 req->cmd = CVAL(inbuf, smb_com);
456 req->flags2 = SVAL(inbuf, smb_flg2);
457 req->smbpid = SVAL(inbuf, smb_pid);
458 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
459 req->seqnum = seqnum;
460 req->vuid = SVAL(inbuf, smb_uid);
461 req->tid = SVAL(inbuf, smb_tid);
462 req->wct = CVAL(inbuf, smb_wct);
463 req->vwv = (uint16_t *)(inbuf+smb_vwv);
464 req->buflen = smb_buflen(inbuf);
465 req->buf = (const uint8_t *)smb_buf(inbuf);
466 req->unread_bytes = unread_bytes;
467 req->encrypted = encrypted;
469 req->conn = conn_find(sconn,req->tid);
470 req->chain_fsp = NULL;
471 req->chain_outbuf = NULL;
474 smb_init_perfcount_data(&req->pcd);
476 /* Ensure we have at least wct words and 2 bytes of bcc. */
477 if (smb_size + req->wct*2 > req_size) {
478 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
479 (unsigned int)req->wct,
480 (unsigned int)req_size));
483 /* Ensure bcc is correct. */
484 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
485 DEBUG(0,("init_smb_request: invalid bcc number %u "
486 "(wct = %u, size %u)\n",
487 (unsigned int)req->buflen,
488 (unsigned int)req->wct,
489 (unsigned int)req_size));
497 static void process_smb(struct smbd_server_connection *conn,
498 uint8_t *inbuf, size_t nread, size_t unread_bytes,
499 uint32_t seqnum, bool encrypted,
500 struct smb_perfcount_data *deferred_pcd);
502 static void smbd_deferred_open_timer(struct event_context *ev,
503 struct timed_event *te,
504 struct timeval _tval,
507 struct pending_message_list *msg = talloc_get_type(private_data,
508 struct pending_message_list);
509 TALLOC_CTX *mem_ctx = talloc_tos();
510 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
513 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
516 exit_server("smbd_deferred_open_timer: talloc failed\n");
520 /* We leave this message on the queue so the open code can
521 know this is a retry. */
522 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
523 (unsigned long long)mid ));
525 /* Mark the message as processed so this is not
526 * re-processed in error. */
527 msg->processed = true;
529 process_smb(smbd_server_conn, inbuf,
531 msg->seqnum, msg->encrypted, &msg->pcd);
533 /* If it's still there and was processed, remove it. */
534 msg = get_deferred_open_message_smb(mid);
535 if (msg && msg->processed) {
536 remove_deferred_open_message_smb(mid);
540 /****************************************************************************
541 Function to push a message onto the tail of a linked list of smb messages ready
543 ****************************************************************************/
545 static bool push_queued_message(struct smb_request *req,
546 struct timeval request_time,
547 struct timeval end_time,
548 char *private_data, size_t private_len)
550 int msg_len = smb_len(req->inbuf) + 4;
551 struct pending_message_list *msg;
553 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
556 DEBUG(0,("push_message: malloc fail (1)\n"));
560 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
561 if(msg->buf.data == NULL) {
562 DEBUG(0,("push_message: malloc fail (2)\n"));
567 msg->request_time = request_time;
568 msg->seqnum = req->seqnum;
569 msg->encrypted = req->encrypted;
570 msg->processed = false;
571 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
574 msg->private_data = data_blob_talloc(msg, private_data,
576 if (msg->private_data.data == NULL) {
577 DEBUG(0,("push_message: malloc fail (3)\n"));
583 msg->te = event_add_timed(smbd_event_context(),
586 smbd_deferred_open_timer,
589 DEBUG(0,("push_message: event_add_timed failed\n"));
594 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
596 DEBUG(10,("push_message: pushed message length %u on "
597 "deferred_open_queue\n", (unsigned int)msg_len));
602 /****************************************************************************
603 Function to delete a sharing violation open message by mid.
604 ****************************************************************************/
606 void remove_deferred_open_message_smb(uint64_t mid)
608 struct pending_message_list *pml;
610 if (smbd_server_conn->using_smb2) {
611 remove_deferred_open_message_smb2(mid);
615 for (pml = deferred_open_queue; pml; pml = pml->next) {
616 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
617 DEBUG(10,("remove_deferred_open_message_smb: "
618 "deleting mid %llu len %u\n",
619 (unsigned long long)mid,
620 (unsigned int)pml->buf.length ));
621 DLIST_REMOVE(deferred_open_queue, pml);
628 /****************************************************************************
629 Move a sharing violation open retry message to the front of the list and
630 schedule it for immediate processing.
631 ****************************************************************************/
633 void schedule_deferred_open_message_smb(uint64_t mid)
635 struct pending_message_list *pml;
638 if (smbd_server_conn->using_smb2) {
639 schedule_deferred_open_message_smb2(mid);
643 for (pml = deferred_open_queue; pml; pml = pml->next) {
644 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
646 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
649 (unsigned long long)msg_mid ));
651 if (mid == msg_mid) {
652 struct timed_event *te;
654 if (pml->processed) {
655 /* A processed message should not be
657 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
658 "message mid %llu was already processed\n",
659 (unsigned long long)msg_mid ));
663 DEBUG(10,("schedule_deferred_open_message_smb: "
664 "scheduling mid %llu\n",
665 (unsigned long long)mid ));
667 te = event_add_timed(smbd_event_context(),
670 smbd_deferred_open_timer,
673 DEBUG(10,("schedule_deferred_open_message_smb: "
674 "event_add_timed() failed, "
675 "skipping mid %llu\n",
676 (unsigned long long)msg_mid ));
679 TALLOC_FREE(pml->te);
681 DLIST_PROMOTE(deferred_open_queue, pml);
686 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
687 "find message mid %llu\n",
688 (unsigned long long)mid ));
691 /****************************************************************************
692 Return true if this mid is on the deferred queue and was not yet processed.
693 ****************************************************************************/
695 bool open_was_deferred(uint64_t mid)
697 struct pending_message_list *pml;
699 if (smbd_server_conn->using_smb2) {
700 return open_was_deferred_smb2(mid);
703 for (pml = deferred_open_queue; pml; pml = pml->next) {
704 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
711 /****************************************************************************
712 Return the message queued by this mid.
713 ****************************************************************************/
715 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
717 struct pending_message_list *pml;
719 for (pml = deferred_open_queue; pml; pml = pml->next) {
720 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
727 /****************************************************************************
728 Get the state data queued by this mid.
729 ****************************************************************************/
731 bool get_deferred_open_message_state(struct smb_request *smbreq,
732 struct timeval *p_request_time,
735 struct pending_message_list *pml;
737 if (smbd_server_conn->using_smb2) {
738 return get_deferred_open_message_state_smb2(smbreq->smb2req,
743 pml = get_deferred_open_message_smb(smbreq->mid);
747 if (p_request_time) {
748 *p_request_time = pml->request_time;
751 *pp_state = (void *)pml->private_data.data;
756 /****************************************************************************
757 Function to push a deferred open smb message onto a linked list of local smb
758 messages ready for processing.
759 ****************************************************************************/
761 bool push_deferred_open_message_smb(struct smb_request *req,
762 struct timeval request_time,
763 struct timeval timeout,
765 char *private_data, size_t priv_len)
767 struct timeval end_time;
770 return push_deferred_open_message_smb2(req->smb2req,
778 if (req->unread_bytes) {
779 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
780 "unread_bytes = %u\n",
781 (unsigned int)req->unread_bytes ));
782 smb_panic("push_deferred_open_message_smb: "
783 "logic error unread_bytes != 0" );
786 end_time = timeval_sum(&request_time, &timeout);
788 DEBUG(10,("push_deferred_open_message_smb: pushing message "
789 "len %u mid %llu timeout time [%u.%06u]\n",
790 (unsigned int) smb_len(req->inbuf)+4,
791 (unsigned long long)req->mid,
792 (unsigned int)end_time.tv_sec,
793 (unsigned int)end_time.tv_usec));
795 return push_queued_message(req, request_time, end_time,
796 private_data, priv_len);
800 struct timed_event *te;
801 struct timeval interval;
803 bool (*handler)(const struct timeval *now, void *private_data);
807 static void smbd_idle_event_handler(struct event_context *ctx,
808 struct timed_event *te,
812 struct idle_event *event =
813 talloc_get_type_abort(private_data, struct idle_event);
815 TALLOC_FREE(event->te);
817 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
818 event->name, event->te));
820 if (!event->handler(&now, event->private_data)) {
821 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
822 event->name, event->te));
823 /* Don't repeat, delete ourselves */
828 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
829 event->name, event->te));
831 event->te = event_add_timed(ctx, event,
832 timeval_sum(&now, &event->interval),
833 smbd_idle_event_handler, event);
835 /* We can't do much but fail here. */
836 SMB_ASSERT(event->te != NULL);
839 struct idle_event *event_add_idle(struct event_context *event_ctx,
841 struct timeval interval,
843 bool (*handler)(const struct timeval *now,
847 struct idle_event *result;
848 struct timeval now = timeval_current();
850 result = TALLOC_P(mem_ctx, struct idle_event);
851 if (result == NULL) {
852 DEBUG(0, ("talloc failed\n"));
856 result->interval = interval;
857 result->handler = handler;
858 result->private_data = private_data;
860 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
861 DEBUG(0, ("talloc failed\n"));
866 result->te = event_add_timed(event_ctx, result,
867 timeval_sum(&now, &interval),
868 smbd_idle_event_handler, result);
869 if (result->te == NULL) {
870 DEBUG(0, ("event_add_timed failed\n"));
875 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
879 static void smbd_sig_term_handler(struct tevent_context *ev,
880 struct tevent_signal *se,
886 exit_server_cleanly("termination signal");
889 void smbd_setup_sig_term_handler(void)
891 struct tevent_signal *se;
893 se = tevent_add_signal(smbd_event_context(),
894 smbd_event_context(),
896 smbd_sig_term_handler,
899 exit_server("failed to setup SIGTERM handler");
903 static void smbd_sig_hup_handler(struct tevent_context *ev,
904 struct tevent_signal *se,
910 change_to_root_user();
911 DEBUG(1,("Reloading services after SIGHUP\n"));
912 reload_services(False);
915 void smbd_setup_sig_hup_handler(void)
917 struct tevent_signal *se;
919 se = tevent_add_signal(smbd_event_context(),
920 smbd_event_context(),
922 smbd_sig_hup_handler,
925 exit_server("failed to setup SIGHUP handler");
929 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
936 to.tv_sec = SMBD_SELECT_TIMEOUT;
940 * Setup the select fd sets.
947 * Are there any timed events waiting ? If so, ensure we don't
948 * select for longer than it would take to wait for them.
955 event_add_to_select_args(smbd_event_context(), &now,
956 &r_fds, &w_fds, &to, &maxfd);
959 /* Process a signal and timed events now... */
960 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
961 return NT_STATUS_RETRY;
966 START_PROFILE(smbd_idle);
968 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
971 END_PROFILE(smbd_idle);
975 if ((conn->smb1.echo_handler.trusted_fd != -1)
976 && FD_ISSET(smbd_server_fd(), &r_fds)
977 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
979 * Prefer to read pending requests from the echo handler. To
980 * quote Jeremy (da70f8ab1): This is a hack of monstrous
983 FD_CLR(smbd_server_fd(), &r_fds);
986 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
987 return NT_STATUS_RETRY;
992 /* something is wrong. Maybe the socket is dead? */
993 return map_nt_error_from_unix(errno);
996 /* Did we timeout ? */
998 return NT_STATUS_RETRY;
1001 /* should not be reached */
1002 return NT_STATUS_INTERNAL_ERROR;
1006 * Only allow 5 outstanding trans requests. We're allocating memory, so
1010 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1013 for (; list != NULL; list = list->next) {
1015 if (list->mid == mid) {
1016 return NT_STATUS_INVALID_PARAMETER;
1022 return NT_STATUS_INSUFFICIENT_RESOURCES;
1025 return NT_STATUS_OK;
1029 These flags determine some of the permissions required to do an operation
1031 Note that I don't set NEED_WRITE on some write operations because they
1032 are used by some brain-dead clients when printing, and I don't want to
1033 force write permissions on print services.
1035 #define AS_USER (1<<0)
1036 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1037 #define TIME_INIT (1<<2)
1038 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1039 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1040 #define DO_CHDIR (1<<6)
1043 define a list of possible SMB messages and their corresponding
1044 functions. Any message that has a NULL function is unimplemented -
1045 please feel free to contribute implementations!
1047 static const struct smb_message_struct {
1049 void (*fn)(struct smb_request *req);
1051 } smb_messages[256] = {
1053 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1054 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1055 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1056 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1057 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1058 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1059 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1060 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1061 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1062 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1063 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1064 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1065 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1066 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1067 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1068 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1069 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1070 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1071 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1072 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1073 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1074 /* 0x15 */ { NULL, NULL, 0 },
1075 /* 0x16 */ { NULL, NULL, 0 },
1076 /* 0x17 */ { NULL, NULL, 0 },
1077 /* 0x18 */ { NULL, NULL, 0 },
1078 /* 0x19 */ { NULL, NULL, 0 },
1079 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1080 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1081 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1082 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1083 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1084 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1085 /* 0x20 */ { "SMBwritec", NULL,0},
1086 /* 0x21 */ { NULL, NULL, 0 },
1087 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1088 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1089 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1090 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1091 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1092 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1093 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1094 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1095 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1096 /* 0x2b */ { "SMBecho",reply_echo,0},
1097 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1098 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1099 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1100 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1101 /* 0x30 */ { NULL, NULL, 0 },
1102 /* 0x31 */ { NULL, NULL, 0 },
1103 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1104 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1105 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1106 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1107 /* 0x36 */ { NULL, NULL, 0 },
1108 /* 0x37 */ { NULL, NULL, 0 },
1109 /* 0x38 */ { NULL, NULL, 0 },
1110 /* 0x39 */ { NULL, NULL, 0 },
1111 /* 0x3a */ { NULL, NULL, 0 },
1112 /* 0x3b */ { NULL, NULL, 0 },
1113 /* 0x3c */ { NULL, NULL, 0 },
1114 /* 0x3d */ { NULL, NULL, 0 },
1115 /* 0x3e */ { NULL, NULL, 0 },
1116 /* 0x3f */ { NULL, NULL, 0 },
1117 /* 0x40 */ { NULL, NULL, 0 },
1118 /* 0x41 */ { NULL, NULL, 0 },
1119 /* 0x42 */ { NULL, NULL, 0 },
1120 /* 0x43 */ { NULL, NULL, 0 },
1121 /* 0x44 */ { NULL, NULL, 0 },
1122 /* 0x45 */ { NULL, NULL, 0 },
1123 /* 0x46 */ { NULL, NULL, 0 },
1124 /* 0x47 */ { NULL, NULL, 0 },
1125 /* 0x48 */ { NULL, NULL, 0 },
1126 /* 0x49 */ { NULL, NULL, 0 },
1127 /* 0x4a */ { NULL, NULL, 0 },
1128 /* 0x4b */ { NULL, NULL, 0 },
1129 /* 0x4c */ { NULL, NULL, 0 },
1130 /* 0x4d */ { NULL, NULL, 0 },
1131 /* 0x4e */ { NULL, NULL, 0 },
1132 /* 0x4f */ { NULL, NULL, 0 },
1133 /* 0x50 */ { NULL, NULL, 0 },
1134 /* 0x51 */ { NULL, NULL, 0 },
1135 /* 0x52 */ { NULL, NULL, 0 },
1136 /* 0x53 */ { NULL, NULL, 0 },
1137 /* 0x54 */ { NULL, NULL, 0 },
1138 /* 0x55 */ { NULL, NULL, 0 },
1139 /* 0x56 */ { NULL, NULL, 0 },
1140 /* 0x57 */ { NULL, NULL, 0 },
1141 /* 0x58 */ { NULL, NULL, 0 },
1142 /* 0x59 */ { NULL, NULL, 0 },
1143 /* 0x5a */ { NULL, NULL, 0 },
1144 /* 0x5b */ { NULL, NULL, 0 },
1145 /* 0x5c */ { NULL, NULL, 0 },
1146 /* 0x5d */ { NULL, NULL, 0 },
1147 /* 0x5e */ { NULL, NULL, 0 },
1148 /* 0x5f */ { NULL, NULL, 0 },
1149 /* 0x60 */ { NULL, NULL, 0 },
1150 /* 0x61 */ { NULL, NULL, 0 },
1151 /* 0x62 */ { NULL, NULL, 0 },
1152 /* 0x63 */ { NULL, NULL, 0 },
1153 /* 0x64 */ { NULL, NULL, 0 },
1154 /* 0x65 */ { NULL, NULL, 0 },
1155 /* 0x66 */ { NULL, NULL, 0 },
1156 /* 0x67 */ { NULL, NULL, 0 },
1157 /* 0x68 */ { NULL, NULL, 0 },
1158 /* 0x69 */ { NULL, NULL, 0 },
1159 /* 0x6a */ { NULL, NULL, 0 },
1160 /* 0x6b */ { NULL, NULL, 0 },
1161 /* 0x6c */ { NULL, NULL, 0 },
1162 /* 0x6d */ { NULL, NULL, 0 },
1163 /* 0x6e */ { NULL, NULL, 0 },
1164 /* 0x6f */ { NULL, NULL, 0 },
1165 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1166 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1167 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1168 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1169 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1170 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1171 /* 0x76 */ { NULL, NULL, 0 },
1172 /* 0x77 */ { NULL, NULL, 0 },
1173 /* 0x78 */ { NULL, NULL, 0 },
1174 /* 0x79 */ { NULL, NULL, 0 },
1175 /* 0x7a */ { NULL, NULL, 0 },
1176 /* 0x7b */ { NULL, NULL, 0 },
1177 /* 0x7c */ { NULL, NULL, 0 },
1178 /* 0x7d */ { NULL, NULL, 0 },
1179 /* 0x7e */ { NULL, NULL, 0 },
1180 /* 0x7f */ { NULL, NULL, 0 },
1181 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1182 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1183 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1184 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1185 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1186 /* 0x85 */ { NULL, NULL, 0 },
1187 /* 0x86 */ { NULL, NULL, 0 },
1188 /* 0x87 */ { NULL, NULL, 0 },
1189 /* 0x88 */ { NULL, NULL, 0 },
1190 /* 0x89 */ { NULL, NULL, 0 },
1191 /* 0x8a */ { NULL, NULL, 0 },
1192 /* 0x8b */ { NULL, NULL, 0 },
1193 /* 0x8c */ { NULL, NULL, 0 },
1194 /* 0x8d */ { NULL, NULL, 0 },
1195 /* 0x8e */ { NULL, NULL, 0 },
1196 /* 0x8f */ { NULL, NULL, 0 },
1197 /* 0x90 */ { NULL, NULL, 0 },
1198 /* 0x91 */ { NULL, NULL, 0 },
1199 /* 0x92 */ { NULL, NULL, 0 },
1200 /* 0x93 */ { NULL, NULL, 0 },
1201 /* 0x94 */ { NULL, NULL, 0 },
1202 /* 0x95 */ { NULL, NULL, 0 },
1203 /* 0x96 */ { NULL, NULL, 0 },
1204 /* 0x97 */ { NULL, NULL, 0 },
1205 /* 0x98 */ { NULL, NULL, 0 },
1206 /* 0x99 */ { NULL, NULL, 0 },
1207 /* 0x9a */ { NULL, NULL, 0 },
1208 /* 0x9b */ { NULL, NULL, 0 },
1209 /* 0x9c */ { NULL, NULL, 0 },
1210 /* 0x9d */ { NULL, NULL, 0 },
1211 /* 0x9e */ { NULL, NULL, 0 },
1212 /* 0x9f */ { NULL, NULL, 0 },
1213 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1214 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1215 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1216 /* 0xa3 */ { NULL, NULL, 0 },
1217 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1218 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1219 /* 0xa6 */ { NULL, NULL, 0 },
1220 /* 0xa7 */ { NULL, NULL, 0 },
1221 /* 0xa8 */ { NULL, NULL, 0 },
1222 /* 0xa9 */ { NULL, NULL, 0 },
1223 /* 0xaa */ { NULL, NULL, 0 },
1224 /* 0xab */ { NULL, NULL, 0 },
1225 /* 0xac */ { NULL, NULL, 0 },
1226 /* 0xad */ { NULL, NULL, 0 },
1227 /* 0xae */ { NULL, NULL, 0 },
1228 /* 0xaf */ { NULL, NULL, 0 },
1229 /* 0xb0 */ { NULL, NULL, 0 },
1230 /* 0xb1 */ { NULL, NULL, 0 },
1231 /* 0xb2 */ { NULL, NULL, 0 },
1232 /* 0xb3 */ { NULL, NULL, 0 },
1233 /* 0xb4 */ { NULL, NULL, 0 },
1234 /* 0xb5 */ { NULL, NULL, 0 },
1235 /* 0xb6 */ { NULL, NULL, 0 },
1236 /* 0xb7 */ { NULL, NULL, 0 },
1237 /* 0xb8 */ { NULL, NULL, 0 },
1238 /* 0xb9 */ { NULL, NULL, 0 },
1239 /* 0xba */ { NULL, NULL, 0 },
1240 /* 0xbb */ { NULL, NULL, 0 },
1241 /* 0xbc */ { NULL, NULL, 0 },
1242 /* 0xbd */ { NULL, NULL, 0 },
1243 /* 0xbe */ { NULL, NULL, 0 },
1244 /* 0xbf */ { NULL, NULL, 0 },
1245 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1246 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1247 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1248 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1249 /* 0xc4 */ { NULL, NULL, 0 },
1250 /* 0xc5 */ { NULL, NULL, 0 },
1251 /* 0xc6 */ { NULL, NULL, 0 },
1252 /* 0xc7 */ { NULL, NULL, 0 },
1253 /* 0xc8 */ { NULL, NULL, 0 },
1254 /* 0xc9 */ { NULL, NULL, 0 },
1255 /* 0xca */ { NULL, NULL, 0 },
1256 /* 0xcb */ { NULL, NULL, 0 },
1257 /* 0xcc */ { NULL, NULL, 0 },
1258 /* 0xcd */ { NULL, NULL, 0 },
1259 /* 0xce */ { NULL, NULL, 0 },
1260 /* 0xcf */ { NULL, NULL, 0 },
1261 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1262 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1263 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1264 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1265 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1266 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1267 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1268 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1269 /* 0xd8 */ { NULL, NULL, 0 },
1270 /* 0xd9 */ { NULL, NULL, 0 },
1271 /* 0xda */ { NULL, NULL, 0 },
1272 /* 0xdb */ { NULL, NULL, 0 },
1273 /* 0xdc */ { NULL, NULL, 0 },
1274 /* 0xdd */ { NULL, NULL, 0 },
1275 /* 0xde */ { NULL, NULL, 0 },
1276 /* 0xdf */ { NULL, NULL, 0 },
1277 /* 0xe0 */ { NULL, NULL, 0 },
1278 /* 0xe1 */ { NULL, NULL, 0 },
1279 /* 0xe2 */ { NULL, NULL, 0 },
1280 /* 0xe3 */ { NULL, NULL, 0 },
1281 /* 0xe4 */ { NULL, NULL, 0 },
1282 /* 0xe5 */ { NULL, NULL, 0 },
1283 /* 0xe6 */ { NULL, NULL, 0 },
1284 /* 0xe7 */ { NULL, NULL, 0 },
1285 /* 0xe8 */ { NULL, NULL, 0 },
1286 /* 0xe9 */ { NULL, NULL, 0 },
1287 /* 0xea */ { NULL, NULL, 0 },
1288 /* 0xeb */ { NULL, NULL, 0 },
1289 /* 0xec */ { NULL, NULL, 0 },
1290 /* 0xed */ { NULL, NULL, 0 },
1291 /* 0xee */ { NULL, NULL, 0 },
1292 /* 0xef */ { NULL, NULL, 0 },
1293 /* 0xf0 */ { NULL, NULL, 0 },
1294 /* 0xf1 */ { NULL, NULL, 0 },
1295 /* 0xf2 */ { NULL, NULL, 0 },
1296 /* 0xf3 */ { NULL, NULL, 0 },
1297 /* 0xf4 */ { NULL, NULL, 0 },
1298 /* 0xf5 */ { NULL, NULL, 0 },
1299 /* 0xf6 */ { NULL, NULL, 0 },
1300 /* 0xf7 */ { NULL, NULL, 0 },
1301 /* 0xf8 */ { NULL, NULL, 0 },
1302 /* 0xf9 */ { NULL, NULL, 0 },
1303 /* 0xfa */ { NULL, NULL, 0 },
1304 /* 0xfb */ { NULL, NULL, 0 },
1305 /* 0xfc */ { NULL, NULL, 0 },
1306 /* 0xfd */ { NULL, NULL, 0 },
1307 /* 0xfe */ { NULL, NULL, 0 },
1308 /* 0xff */ { NULL, NULL, 0 }
1312 /*******************************************************************
1313 allocate and initialize a reply packet
1314 ********************************************************************/
1316 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1317 const char *inbuf, char **outbuf, uint8_t num_words,
1321 * Protect against integer wrap
1323 if ((num_bytes > 0xffffff)
1324 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1326 if (asprintf(&msg, "num_bytes too large: %u",
1327 (unsigned)num_bytes) == -1) {
1328 msg = CONST_DISCARD(char *, "num_bytes too large");
1333 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1334 smb_size + num_words*2 + num_bytes);
1335 if (*outbuf == NULL) {
1339 construct_reply_common(req, inbuf, *outbuf);
1340 srv_set_message(*outbuf, num_words, num_bytes, false);
1342 * Zero out the word area, the caller has to take care of the bcc area
1345 if (num_words != 0) {
1346 memset(*outbuf + smb_vwv0, 0, num_words*2);
1352 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1355 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1357 smb_panic("could not allocate output buffer\n");
1359 req->outbuf = (uint8_t *)outbuf;
1363 /*******************************************************************
1364 Dump a packet to a file.
1365 ********************************************************************/
1367 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1371 if (DEBUGLEVEL < 50) {
1375 if (len < 4) len = smb_len(data)+4;
1376 for (i=1;i<100;i++) {
1377 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1378 type ? "req" : "resp") == -1) {
1381 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1382 if (fd != -1 || errno != EEXIST) break;
1385 ssize_t ret = write(fd, data, len);
1387 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1389 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1394 /****************************************************************************
1395 Prepare everything for calling the actual request function, and potentially
1396 call the request function via the "new" interface.
1398 Return False if the "legacy" function needs to be called, everything is
1401 Return True if we're done.
1403 I know this API sucks, but it is the one with the least code change I could
1405 ****************************************************************************/
1407 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1411 connection_struct *conn = NULL;
1412 struct smbd_server_connection *sconn = smbd_server_conn;
1416 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1417 * so subtract 4 from it. */
1418 if (!valid_smb_header(req->inbuf)
1419 || (size < (smb_size - 4))) {
1420 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1421 smb_len(req->inbuf)));
1422 exit_server_cleanly("Non-SMB packet");
1425 if (smb_messages[type].fn == NULL) {
1426 DEBUG(0,("Unknown message type %d!\n",type));
1427 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1428 reply_unknown_new(req, type);
1432 flags = smb_messages[type].flags;
1434 /* In share mode security we must ignore the vuid. */
1435 session_tag = (lp_security() == SEC_SHARE)
1436 ? UID_FIELD_INVALID : req->vuid;
1439 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1440 (int)sys_getpid(), (unsigned long)conn));
1442 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1444 /* Ensure this value is replaced in the incoming packet. */
1445 SSVAL(req->inbuf,smb_uid,session_tag);
1448 * Ensure the correct username is in current_user_info. This is a
1449 * really ugly bugfix for problems with multiple session_setup_and_X's
1450 * being done and allowing %U and %G substitutions to work correctly.
1451 * There is a reason this code is done here, don't move it unless you
1452 * know what you're doing... :-).
1456 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1457 user_struct *vuser = NULL;
1459 sconn->smb1.sessions.last_session_tag = session_tag;
1460 if(session_tag != UID_FIELD_INVALID) {
1461 vuser = get_valid_user_struct(sconn, session_tag);
1463 set_current_user_info(
1464 vuser->server_info->sanitized_username,
1465 vuser->server_info->unix_name,
1466 vuser->server_info->info3->base.domain.string);
1471 /* Does this call need to be run as the connected user? */
1472 if (flags & AS_USER) {
1474 /* Does this call need a valid tree connection? */
1477 * Amazingly, the error code depends on the command
1480 if (type == SMBntcreateX) {
1481 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1483 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1488 if (!change_to_user(conn,session_tag)) {
1489 DEBUG(0, ("Error: Could not change to user. Removing "
1490 "deferred open, mid=%llu.\n",
1491 (unsigned long long)req->mid));
1492 reply_force_doserror(req, ERRSRV, ERRbaduid);
1496 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1498 /* Does it need write permission? */
1499 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1500 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1504 /* IPC services are limited */
1505 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1506 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1510 /* This call needs to be run as root */
1511 change_to_root_user();
1514 /* load service specific parameters */
1516 if (req->encrypted) {
1517 conn->encrypted_tid = true;
1518 /* encrypted required from now on. */
1519 conn->encrypt_level = Required;
1520 } else if (ENCRYPTION_REQUIRED(conn)) {
1521 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1522 exit_server_cleanly("encryption required "
1528 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1529 (flags & (AS_USER|DO_CHDIR)
1531 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1534 conn->num_smb_operations++;
1537 /* does this protocol need to be run as guest? */
1538 if ((flags & AS_GUEST)
1539 && (!change_to_guest() ||
1540 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1541 lp_hostsdeny(-1)))) {
1542 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1546 smb_messages[type].fn(req);
1550 /****************************************************************************
1551 Construct a reply to the incoming packet.
1552 ****************************************************************************/
1554 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1555 uint32_t seqnum, bool encrypted,
1556 struct smb_perfcount_data *deferred_pcd)
1558 connection_struct *conn;
1559 struct smb_request *req;
1561 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1562 smb_panic("could not allocate smb_request");
1565 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1567 exit_server_cleanly("Invalid SMB request");
1570 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1572 /* we popped this message off the queue - keep original perf data */
1574 req->pcd = *deferred_pcd;
1576 SMB_PERFCOUNT_START(&req->pcd);
1577 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1578 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1581 conn = switch_message(req->cmd, req, size);
1583 if (req->unread_bytes) {
1584 /* writeX failed. drain socket. */
1585 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1586 req->unread_bytes) {
1587 smb_panic("failed to drain pending bytes");
1589 req->unread_bytes = 0;
1597 if (req->outbuf == NULL) {
1601 if (CVAL(req->outbuf,0) == 0) {
1602 show_msg((char *)req->outbuf);
1605 if (!srv_send_smb(smbd_server_fd(),
1606 (char *)req->outbuf,
1607 true, req->seqnum+1,
1608 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1610 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1618 /****************************************************************************
1619 Process an smb from the client
1620 ****************************************************************************/
1621 static void process_smb(struct smbd_server_connection *conn,
1622 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1623 uint32_t seqnum, bool encrypted,
1624 struct smb_perfcount_data *deferred_pcd)
1626 int msg_type = CVAL(inbuf,0);
1628 DO_PROFILE_INC(smb_count);
1630 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1632 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1634 (unsigned int)unread_bytes ));
1636 if (msg_type != 0) {
1638 * NetBIOS session request, keepalive, etc.
1640 reply_special((char *)inbuf);
1644 if (smbd_server_conn->using_smb2) {
1645 /* At this point we're not really using smb2,
1646 * we make the decision here.. */
1647 if (smbd_is_smb2_header(inbuf, nread)) {
1648 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1650 } else if (nread >= smb_size && valid_smb_header(inbuf)
1651 && CVAL(inbuf, smb_com) != 0x72) {
1652 /* This is a non-negprot SMB1 packet.
1653 Disable SMB2 from now on. */
1654 smbd_server_conn->using_smb2 = false;
1658 show_msg((char *)inbuf);
1660 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1664 conn->smb1.num_requests++;
1666 /* The timeout_processing function isn't run nearly
1667 often enough to implement 'max log size' without
1668 overrunning the size of the file by many megabytes.
1669 This is especially true if we are running at debug
1670 level 10. Checking every 50 SMBs is a nice
1671 tradeoff of performance vs log file size overrun. */
1673 if ((conn->smb1.num_requests % 50) == 0 &&
1674 need_to_check_log_size()) {
1675 change_to_root_user();
1680 /****************************************************************************
1681 Return a string containing the function name of a SMB command.
1682 ****************************************************************************/
1684 const char *smb_fn_name(int type)
1686 const char *unknown_name = "SMBunknown";
1688 if (smb_messages[type].name == NULL)
1689 return(unknown_name);
1691 return(smb_messages[type].name);
1694 /****************************************************************************
1695 Helper functions for contruct_reply.
1696 ****************************************************************************/
1698 void add_to_common_flags2(uint32 v)
1703 void remove_from_common_flags2(uint32 v)
1705 common_flags2 &= ~v;
1708 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1711 srv_set_message(outbuf,0,0,false);
1713 SCVAL(outbuf, smb_com, req->cmd);
1714 SIVAL(outbuf,smb_rcls,0);
1715 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1716 SSVAL(outbuf,smb_flg2,
1717 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1719 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1721 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1722 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1723 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1724 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1727 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1729 construct_reply_common(req, (char *)req->inbuf, outbuf);
1733 * How many bytes have we already accumulated up to the current wct field
1737 size_t req_wct_ofs(struct smb_request *req)
1741 if (req->chain_outbuf == NULL) {
1744 buf_size = talloc_get_size(req->chain_outbuf);
1745 if ((buf_size % 4) != 0) {
1746 buf_size += (4 - (buf_size % 4));
1748 return buf_size - 4;
1752 * Hack around reply_nterror & friends not being aware of chained requests,
1753 * generating illegal (i.e. wct==0) chain replies.
1756 static void fixup_chain_error_packet(struct smb_request *req)
1758 uint8_t *outbuf = req->outbuf;
1760 reply_outbuf(req, 2, 0);
1761 memcpy(req->outbuf, outbuf, smb_wct);
1762 TALLOC_FREE(outbuf);
1763 SCVAL(req->outbuf, smb_vwv0, 0xff);
1767 * @brief Find the smb_cmd offset of the last command pushed
1768 * @param[in] buf The buffer we're building up
1769 * @retval Where can we put our next andx cmd?
1771 * While chaining requests, the "next" request we're looking at needs to put
1772 * its SMB_Command before the data the previous request already built up added
1773 * to the chain. Find the offset to the place where we have to put our cmd.
1776 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1781 cmd = CVAL(buf, smb_com);
1783 SMB_ASSERT(is_andx_req(cmd));
1787 while (CVAL(buf, ofs) != 0xff) {
1789 if (!is_andx_req(CVAL(buf, ofs))) {
1794 * ofs is from start of smb header, so add the 4 length
1795 * bytes. The next cmd is right after the wct field.
1797 ofs = SVAL(buf, ofs+2) + 4 + 1;
1799 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1807 * @brief Do the smb chaining at a buffer level
1808 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1809 * @param[in] smb_command The command that we want to issue
1810 * @param[in] wct How many words?
1811 * @param[in] vwv The words, already in network order
1812 * @param[in] bytes_alignment How shall we align "bytes"?
1813 * @param[in] num_bytes How many bytes?
1814 * @param[in] bytes The data the request ships
1816 * smb_splice_chain() adds the vwv and bytes to the request already present in
1820 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1821 uint8_t wct, const uint16_t *vwv,
1822 size_t bytes_alignment,
1823 uint32_t num_bytes, const uint8_t *bytes)
1826 size_t old_size, new_size;
1828 size_t chain_padding = 0;
1829 size_t bytes_padding = 0;
1832 old_size = talloc_get_size(*poutbuf);
1835 * old_size == smb_wct means we're pushing the first request in for
1839 first_request = (old_size == smb_wct);
1841 if (!first_request && ((old_size % 4) != 0)) {
1843 * Align the wct field of subsequent requests to a 4-byte
1846 chain_padding = 4 - (old_size % 4);
1850 * After the old request comes the new wct field (1 byte), the vwv's
1851 * and the num_bytes field. After at we might need to align the bytes
1852 * given to us to "bytes_alignment", increasing the num_bytes value.
1855 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1857 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1858 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1861 new_size += bytes_padding + num_bytes;
1863 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1864 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1865 (unsigned)new_size));
1869 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1870 if (outbuf == NULL) {
1871 DEBUG(0, ("talloc failed\n"));
1876 if (first_request) {
1877 SCVAL(outbuf, smb_com, smb_command);
1879 size_t andx_cmd_ofs;
1881 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1882 DEBUG(1, ("invalid command chain\n"));
1883 *poutbuf = TALLOC_REALLOC_ARRAY(
1884 NULL, *poutbuf, uint8_t, old_size);
1888 if (chain_padding != 0) {
1889 memset(outbuf + old_size, 0, chain_padding);
1890 old_size += chain_padding;
1893 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1894 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1900 * Push the chained request:
1905 SCVAL(outbuf, ofs, wct);
1912 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1913 ofs += sizeof(uint16_t) * wct;
1919 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1920 ofs += sizeof(uint16_t);
1926 if (bytes_padding != 0) {
1927 memset(outbuf + ofs, 0, bytes_padding);
1928 ofs += bytes_padding;
1935 memcpy(outbuf + ofs, bytes, num_bytes);
1940 /****************************************************************************
1941 Construct a chained reply and add it to the already made reply
1942 ****************************************************************************/
1944 void chain_reply(struct smb_request *req)
1946 size_t smblen = smb_len(req->inbuf);
1947 size_t already_used, length_needed;
1949 uint32_t chain_offset; /* uint32_t to avoid overflow */
1956 if (IVAL(req->outbuf, smb_rcls) != 0) {
1957 fixup_chain_error_packet(req);
1961 * Any of the AndX requests and replies have at least a wct of
1962 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1963 * beginning of the SMB header to the next wct field.
1965 * None of the AndX requests put anything valuable in vwv[0] and [1],
1966 * so we can overwrite it here to form the chain.
1969 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1970 if (req->chain_outbuf == NULL) {
1971 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1972 req, req->outbuf, uint8_t,
1973 smb_len(req->outbuf) + 4);
1974 if (req->chain_outbuf == NULL) {
1975 smb_panic("talloc failed");
1983 * Here we assume that this is the end of the chain. For that we need
1984 * to set "next command" to 0xff and the offset to 0. If we later find
1985 * more commands in the chain, this will be overwritten again.
1988 SCVAL(req->outbuf, smb_vwv0, 0xff);
1989 SCVAL(req->outbuf, smb_vwv0+1, 0);
1990 SSVAL(req->outbuf, smb_vwv1, 0);
1992 if (req->chain_outbuf == NULL) {
1994 * In req->chain_outbuf we collect all the replies. Start the
1995 * chain by copying in the first reply.
1997 * We do the realloc because later on we depend on
1998 * talloc_get_size to determine the length of
1999 * chain_outbuf. The reply_xxx routines might have
2000 * over-allocated (reply_pipe_read_and_X used to be such an
2003 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2004 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2005 if (req->chain_outbuf == NULL) {
2006 smb_panic("talloc failed");
2011 * Update smb headers where subsequent chained commands
2012 * may have updated them.
2014 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2015 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2017 if (!smb_splice_chain(&req->chain_outbuf,
2018 CVAL(req->outbuf, smb_com),
2019 CVAL(req->outbuf, smb_wct),
2020 (uint16_t *)(req->outbuf + smb_vwv),
2021 0, smb_buflen(req->outbuf),
2022 (uint8_t *)smb_buf(req->outbuf))) {
2025 TALLOC_FREE(req->outbuf);
2029 * We use the old request's vwv field to grab the next chained command
2030 * and offset into the chained fields.
2033 chain_cmd = CVAL(req->vwv+0, 0);
2034 chain_offset = SVAL(req->vwv+1, 0);
2036 if (chain_cmd == 0xff) {
2038 * End of chain, no more requests from the client. So ship the
2041 smb_setlen((char *)(req->chain_outbuf),
2042 talloc_get_size(req->chain_outbuf) - 4);
2044 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2045 true, req->seqnum+1,
2046 IS_CONN_ENCRYPTED(req->conn)
2049 exit_server_cleanly("chain_reply: srv_send_smb "
2052 TALLOC_FREE(req->chain_outbuf);
2057 /* add a new perfcounter for this element of chain */
2058 SMB_PERFCOUNT_ADD(&req->pcd);
2059 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2060 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2063 * Check if the client tries to fool us. The request so far uses the
2064 * space to the end of the byte buffer in the request just
2065 * processed. The chain_offset can't point into that area. If that was
2066 * the case, we could end up with an endless processing of the chain,
2067 * we would always handle the same request.
2070 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2071 if (chain_offset < already_used) {
2076 * Next check: Make sure the chain offset does not point beyond the
2077 * overall smb request length.
2080 length_needed = chain_offset+1; /* wct */
2081 if (length_needed > smblen) {
2086 * Now comes the pointer magic. Goal here is to set up req->vwv and
2087 * req->buf correctly again to be able to call the subsequent
2088 * switch_message(). The chain offset (the former vwv[1]) points at
2089 * the new wct field.
2092 wct = CVAL(smb_base(req->inbuf), chain_offset);
2095 * Next consistency check: Make the new vwv array fits in the overall
2099 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2100 if (length_needed > smblen) {
2103 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2106 * Now grab the new byte buffer....
2109 buflen = SVAL(vwv+wct, 0);
2112 * .. and check that it fits.
2115 length_needed += buflen;
2116 if (length_needed > smblen) {
2119 buf = (uint8_t *)(vwv+wct+1);
2121 req->cmd = chain_cmd;
2124 req->buflen = buflen;
2127 switch_message(chain_cmd, req, smblen);
2129 if (req->outbuf == NULL) {
2131 * This happens if the chained command has suspended itself or
2132 * if it has called srv_send_smb() itself.
2138 * We end up here if the chained command was not itself chained or
2139 * suspended, but for example a close() command. We now need to splice
2140 * the chained commands' outbuf into the already built up chain_outbuf
2141 * and ship the result.
2147 * We end up here if there's any error in the chain syntax. Report a
2148 * DOS error, just like Windows does.
2150 reply_force_doserror(req, ERRSRV, ERRerror);
2151 fixup_chain_error_packet(req);
2155 * This scary statement intends to set the
2156 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2157 * to the value req->outbuf carries
2159 SSVAL(req->chain_outbuf, smb_flg2,
2160 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2161 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2164 * Transfer the error codes from the subrequest to the main one
2166 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2167 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2169 if (!smb_splice_chain(&req->chain_outbuf,
2170 CVAL(req->outbuf, smb_com),
2171 CVAL(req->outbuf, smb_wct),
2172 (uint16_t *)(req->outbuf + smb_vwv),
2173 0, smb_buflen(req->outbuf),
2174 (uint8_t *)smb_buf(req->outbuf))) {
2175 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2177 TALLOC_FREE(req->outbuf);
2179 smb_setlen((char *)(req->chain_outbuf),
2180 talloc_get_size(req->chain_outbuf) - 4);
2182 show_msg((char *)(req->chain_outbuf));
2184 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2185 true, req->seqnum+1,
2186 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2188 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2190 TALLOC_FREE(req->chain_outbuf);
2194 /****************************************************************************
2195 Check if services need reloading.
2196 ****************************************************************************/
2198 void check_reload(time_t t)
2200 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2202 if(last_smb_conf_reload_time == 0) {
2203 last_smb_conf_reload_time = t;
2204 /* Our printing subsystem might not be ready at smbd start up.
2205 Then no printer is available till the first printers check
2206 is performed. A lower initial interval circumvents this. */
2207 if ( printcap_cache_time > 60 )
2208 last_printer_reload_time = t - printcap_cache_time + 60;
2210 last_printer_reload_time = t;
2213 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2214 /* randomize over 60 second the printcap reload to avoid all
2215 * process hitting cupsd at the same time */
2216 int time_range = 60;
2218 last_printer_reload_time += random() % time_range;
2222 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2223 reload_services(True);
2224 last_smb_conf_reload_time = t;
2227 /* 'printcap cache time = 0' disable the feature */
2229 if ( printcap_cache_time != 0 )
2231 /* see if it's time to reload or if the clock has been set back */
2233 if ( (t >= last_printer_reload_time+printcap_cache_time)
2234 || (t-last_printer_reload_time < 0) )
2236 DEBUG( 3,( "Printcap cache time expired.\n"));
2238 last_printer_reload_time = t;
2243 static bool fd_is_readable(int fd)
2246 struct timeval timeout = {0, };
2252 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2256 return FD_ISSET(fd, &fds);
2259 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2261 /* TODO: make write nonblocking */
2264 static void smbd_server_connection_read_handler(
2265 struct smbd_server_connection *conn, int fd)
2267 uint8_t *inbuf = NULL;
2268 size_t inbuf_len = 0;
2269 size_t unread_bytes = 0;
2270 bool encrypted = false;
2271 TALLOC_CTX *mem_ctx = talloc_tos();
2275 bool from_client = (smbd_server_fd() == fd)?true:false;
2278 smbd_lock_socket(conn);
2280 if (!fd_is_readable(smbd_server_fd())) {
2281 DEBUG(10,("the echo listener was faster\n"));
2282 smbd_unlock_socket(conn);
2286 /* TODO: make this completely nonblocking */
2287 status = receive_smb_talloc(mem_ctx, fd,
2288 (char **)(void *)&inbuf,
2292 &inbuf_len, &seqnum,
2293 false /* trusted channel */);
2294 smbd_unlock_socket(conn);
2296 /* TODO: make this completely nonblocking */
2297 status = receive_smb_talloc(mem_ctx, fd,
2298 (char **)(void *)&inbuf,
2302 &inbuf_len, &seqnum,
2303 true /* trusted channel */);
2306 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2309 if (NT_STATUS_IS_ERR(status)) {
2310 exit_server_cleanly("failed to receive smb request");
2312 if (!NT_STATUS_IS_OK(status)) {
2317 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2318 seqnum, encrypted, NULL);
2321 static void smbd_server_connection_handler(struct event_context *ev,
2322 struct fd_event *fde,
2326 struct smbd_server_connection *conn = talloc_get_type(private_data,
2327 struct smbd_server_connection);
2329 if (flags & EVENT_FD_WRITE) {
2330 smbd_server_connection_write_handler(conn);
2331 } else if (flags & EVENT_FD_READ) {
2332 smbd_server_connection_read_handler(conn, smbd_server_fd());
2336 static void smbd_server_echo_handler(struct event_context *ev,
2337 struct fd_event *fde,
2341 struct smbd_server_connection *conn = talloc_get_type(private_data,
2342 struct smbd_server_connection);
2344 if (flags & EVENT_FD_WRITE) {
2345 smbd_server_connection_write_handler(conn);
2346 } else if (flags & EVENT_FD_READ) {
2347 smbd_server_connection_read_handler(
2348 conn, conn->smb1.echo_handler.trusted_fd);
2352 /****************************************************************************
2353 received when we should release a specific IP
2354 ****************************************************************************/
2355 static void release_ip(const char *ip, void *priv)
2357 char addr[INET6_ADDRSTRLEN];
2360 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2362 if (strncmp("::ffff:", addr, 7) == 0) {
2366 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2367 /* we can't afford to do a clean exit - that involves
2368 database writes, which would potentially mean we
2369 are still running after the failover has finished -
2370 we have to get rid of this process ID straight
2372 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2374 /* note we must exit with non-zero status so the unclean handler gets
2375 called in the parent, so that the brl database is tickled */
2380 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2381 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2383 release_ip((char *)data->data, NULL);
2386 #ifdef CLUSTER_SUPPORT
2387 static int client_get_tcp_info(struct sockaddr_storage *server,
2388 struct sockaddr_storage *client)
2391 if (server_fd == -1) {
2394 length = sizeof(*server);
2395 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2398 length = sizeof(*client);
2399 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2407 * Send keepalive packets to our client
2409 static bool keepalive_fn(const struct timeval *now, void *private_data)
2411 struct smbd_server_connection *sconn = smbd_server_conn;
2414 if (sconn->using_smb2) {
2415 /* Don't do keepalives on an SMB2 connection. */
2419 smbd_lock_socket(smbd_server_conn);
2420 ret = send_keepalive(smbd_server_fd());
2421 smbd_unlock_socket(smbd_server_conn);
2424 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2431 * Do the recurring check if we're idle
2433 static bool deadtime_fn(const struct timeval *now, void *private_data)
2435 struct smbd_server_connection *sconn = smbd_server_conn;
2437 if (sconn->using_smb2) {
2438 /* TODO: implement real idle check */
2439 if (sconn->smb2.sessions.list) {
2442 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2443 messaging_send(smbd_messaging_context(), procid_self(),
2444 MSG_SHUTDOWN, &data_blob_null);
2448 if ((conn_num_open(sconn) == 0)
2449 || (conn_idle_all(sconn, now->tv_sec))) {
2450 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2451 messaging_send(smbd_messaging_context(), procid_self(),
2452 MSG_SHUTDOWN, &data_blob_null);
2460 * Do the recurring log file and smb.conf reload checks.
2463 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2465 change_to_root_user();
2467 /* update printer queue caches if necessary */
2468 update_monitored_printq_cache();
2470 /* check if we need to reload services */
2471 check_reload(time(NULL));
2473 /* Change machine password if neccessary. */
2474 attempt_machine_password_change();
2477 * Force a log file check.
2479 force_check_log_size();
2484 static int create_unlink_tmp(const char *dir)
2489 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2490 if (fname == NULL) {
2494 fd = mkstemp(fname);
2499 if (unlink(fname) == -1) {
2500 int sys_errno = errno;
2510 struct smbd_echo_state {
2511 struct tevent_context *ev;
2512 struct iovec *pending;
2513 struct smbd_server_connection *sconn;
2516 struct tevent_fd *parent_fde;
2518 struct tevent_fd *read_fde;
2519 struct tevent_req *write_req;
2522 static void smbd_echo_writer_done(struct tevent_req *req);
2524 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2528 if (state->write_req != NULL) {
2532 num_pending = talloc_array_length(state->pending);
2533 if (num_pending == 0) {
2537 state->write_req = writev_send(state, state->ev, NULL,
2538 state->parent_pipe, false,
2539 state->pending, num_pending);
2540 if (state->write_req == NULL) {
2541 DEBUG(1, ("writev_send failed\n"));
2545 talloc_steal(state->write_req, state->pending);
2546 state->pending = NULL;
2548 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2552 static void smbd_echo_writer_done(struct tevent_req *req)
2554 struct smbd_echo_state *state = tevent_req_callback_data(
2555 req, struct smbd_echo_state);
2559 written = writev_recv(req, &err);
2561 state->write_req = NULL;
2562 if (written == -1) {
2563 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2566 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2567 smbd_echo_activate_writer(state);
2570 static bool smbd_echo_reply(int fd,
2571 uint8_t *inbuf, size_t inbuf_len,
2574 struct smb_request req;
2575 uint16_t num_replies;
2580 if (inbuf_len < smb_size) {
2581 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2584 if (!valid_smb_header(inbuf)) {
2585 DEBUG(10, ("Got invalid SMB header\n"));
2589 if (!init_smb_request(&req, inbuf, 0, false, seqnum)) {
2594 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2595 smb_messages[req.cmd].name
2596 ? smb_messages[req.cmd].name : "unknown"));
2598 if (req.cmd != SMBecho) {
2605 num_replies = SVAL(req.vwv+0, 0);
2606 if (num_replies != 1) {
2607 /* Not a Windows "Hey, you're still there?" request */
2611 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2613 DEBUG(10, ("create_outbuf failed\n"));
2616 req.outbuf = (uint8_t *)outbuf;
2618 SSVAL(req.outbuf, smb_vwv0, num_replies);
2620 if (req.buflen > 0) {
2621 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2624 out_len = smb_len(req.outbuf) + 4;
2626 ok = srv_send_smb(smbd_server_fd(),
2630 TALLOC_FREE(outbuf);
2638 static void smbd_echo_exit(struct tevent_context *ev,
2639 struct tevent_fd *fde, uint16_t flags,
2642 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2646 static void smbd_echo_reader(struct tevent_context *ev,
2647 struct tevent_fd *fde, uint16_t flags,
2650 struct smbd_echo_state *state = talloc_get_type_abort(
2651 private_data, struct smbd_echo_state);
2652 struct smbd_server_connection *sconn = state->sconn;
2653 size_t unread, num_pending;
2656 uint32_t seqnum = 0;
2659 bool encrypted = false;
2661 ok = smbd_lock_socket_internal(sconn);
2663 DEBUG(0, ("%s: failed to lock socket\n",
2668 if (!fd_is_readable(smbd_server_fd())) {
2669 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2670 (int)sys_getpid()));
2671 ok = smbd_unlock_socket_internal(sconn);
2673 DEBUG(1, ("%s: failed to unlock socket in\n",
2680 num_pending = talloc_array_length(state->pending);
2681 tmp = talloc_realloc(state, state->pending, struct iovec,
2684 DEBUG(1, ("talloc_realloc failed\n"));
2687 state->pending = tmp;
2689 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2691 status = receive_smb_talloc(state->pending, smbd_server_fd(),
2692 (char **)(void *)&state->pending[num_pending].iov_base,
2696 &state->pending[num_pending].iov_len,
2698 false /* trusted_channel*/);
2699 if (!NT_STATUS_IS_OK(status)) {
2700 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2701 (int)sys_getpid(), nt_errstr(status)));
2705 ok = smbd_unlock_socket_internal(sconn);
2707 DEBUG(1, ("%s: failed to unlock socket in\n",
2713 * place the seqnum in the packet so that the main process can reply
2716 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2717 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2719 reply = smbd_echo_reply(smbd_server_fd(),
2720 (uint8_t *)state->pending[num_pending].iov_base,
2721 state->pending[num_pending].iov_len,
2724 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2725 /* no check, shrinking by some bytes does not fail */
2726 state->pending = talloc_realloc(state, state->pending,
2730 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2731 smbd_echo_activate_writer(state);
2735 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2738 struct smbd_echo_state *state;
2740 state = talloc_zero(sconn, struct smbd_echo_state);
2741 if (state == NULL) {
2742 DEBUG(1, ("talloc failed\n"));
2745 state->sconn = sconn;
2746 state->parent_pipe = parent_pipe;
2747 state->ev = s3_tevent_context_init(state);
2748 if (state->ev == NULL) {
2749 DEBUG(1, ("tevent_context_init failed\n"));
2753 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2754 TEVENT_FD_READ, smbd_echo_exit,
2756 if (state->parent_fde == NULL) {
2757 DEBUG(1, ("tevent_add_fd failed\n"));
2761 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2762 TEVENT_FD_READ, smbd_echo_reader,
2764 if (state->read_fde == NULL) {
2765 DEBUG(1, ("tevent_add_fd failed\n"));
2771 if (tevent_loop_once(state->ev) == -1) {
2772 DEBUG(1, ("tevent_loop_once failed: %s\n",
2781 * Handle SMBecho requests in a forked child process
2783 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2785 int listener_pipe[2];
2789 res = pipe(listener_pipe);
2791 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2794 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2795 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2796 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2804 close(listener_pipe[0]);
2806 status = reinit_after_fork(smbd_messaging_context(),
2807 smbd_event_context(), false);
2808 if (!NT_STATUS_IS_OK(status)) {
2809 DEBUG(1, ("reinit_after_fork failed: %s\n",
2810 nt_errstr(status)));
2813 smbd_echo_loop(sconn, listener_pipe[1]);
2816 close(listener_pipe[1]);
2817 listener_pipe[1] = -1;
2818 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2820 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2823 * Without smb signing this is the same as the normal smbd
2824 * listener. This needs to change once signing comes in.
2826 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2828 sconn->smb1.echo_handler.trusted_fd,
2830 smbd_server_echo_handler,
2832 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2833 DEBUG(1, ("event_add_fd failed\n"));
2840 if (listener_pipe[0] != -1) {
2841 close(listener_pipe[0]);
2843 if (listener_pipe[1] != -1) {
2844 close(listener_pipe[1]);
2846 sconn->smb1.echo_handler.trusted_fd = -1;
2847 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2848 close(sconn->smb1.echo_handler.socket_lock_fd);
2850 sconn->smb1.echo_handler.trusted_fd = -1;
2851 sconn->smb1.echo_handler.socket_lock_fd = -1;
2855 /****************************************************************************
2856 Process commands from the client
2857 ****************************************************************************/
2859 void smbd_process(void)
2861 TALLOC_CTX *frame = talloc_stackframe();
2862 struct sockaddr_storage ss;
2863 struct sockaddr *sa = NULL;
2865 struct tsocket_address *local_address = NULL;
2866 struct tsocket_address *remote_address = NULL;
2867 const char *remaddr = NULL;
2870 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2871 lp_security() != SEC_SHARE &&
2872 !lp_async_smb_echo_handler()) {
2874 * We're not making the desion here,
2875 * we're just allowing the client
2876 * to decide between SMB1 and SMB2
2877 * with the first negprot
2880 smbd_server_conn->using_smb2 = true;
2883 /* Ensure child is set to blocking mode */
2884 set_blocking(smbd_server_fd(),True);
2886 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2887 set_socket_options(smbd_server_fd(), lp_socket_options());
2889 sa = (struct sockaddr *)(void *)&ss;
2890 sa_len = sizeof(ss);
2891 ret = getpeername(smbd_server_fd(), sa, &sa_len);
2893 int level = (errno == ENOTCONN)?2:0;
2894 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2895 exit_server("getpeername() failed.\n");
2897 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2901 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2902 __location__, strerror(errno)));
2903 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2906 sa = (struct sockaddr *)(void *)&ss;
2907 sa_len = sizeof(ss);
2908 ret = getsockname(smbd_server_fd(), sa, &sa_len);
2910 int level = (errno == ENOTCONN)?2:0;
2911 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2912 exit_server("getsockname() failed.\n");
2914 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2918 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2919 __location__, strerror(errno)));
2920 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2923 smbd_server_conn->local_address = local_address;
2924 smbd_server_conn->remote_address = remote_address;
2926 if (tsocket_address_is_inet(remote_address, "ip")) {
2927 remaddr = tsocket_address_inet_addr_string(
2928 smbd_server_conn->remote_address,
2930 if (remaddr == NULL) {
2934 remaddr = "0.0.0.0";
2937 /* this is needed so that we get decent entries
2938 in smbstatus for port 445 connects */
2939 set_remote_machine_name(remaddr, false);
2940 reload_services(true);
2943 * Before the first packet, check the global hosts allow/ hosts deny
2944 * parameters before doing any parsing of packets passed to us by the
2945 * client. This prevents attacks on our parsing code from hosts not in
2946 * the hosts allow list.
2949 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2950 lp_hostsdeny(-1))) {
2952 * send a negative session response "not listening on calling
2955 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2956 DEBUG( 1, ("Connection denied from %s to %s\n",
2957 tsocket_address_string(remote_address, talloc_tos()),
2958 tsocket_address_string(local_address, talloc_tos())));
2959 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2961 exit_server_cleanly("connection denied");
2964 DEBUG(10, ("Connection allowed from %s to %s\n",
2965 tsocket_address_string(remote_address, talloc_tos()),
2966 tsocket_address_string(local_address, talloc_tos())));
2972 smb_perfcount_init();
2974 if (!init_account_policy()) {
2975 exit_server("Could not open account policy tdb.\n");
2978 if (*lp_rootdir()) {
2979 if (chroot(lp_rootdir()) != 0) {
2980 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2981 exit_server("Failed to chroot()");
2983 if (chdir("/") == -1) {
2984 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2985 exit_server("Failed to chroot()");
2987 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2990 if (!srv_init_signing(smbd_server_conn)) {
2991 exit_server("Failed to init smb_signing");
2994 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2995 exit_server("Failed to fork echo handler");
2999 if (!init_oplocks(smbd_messaging_context()))
3000 exit_server("Failed to init oplocks");
3002 /* register our message handlers */
3003 messaging_register(smbd_messaging_context(), NULL,
3004 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3005 messaging_register(smbd_messaging_context(), NULL,
3006 MSG_SMB_RELEASE_IP, msg_release_ip);
3007 messaging_register(smbd_messaging_context(), NULL,
3008 MSG_SMB_CLOSE_FILE, msg_close_file);
3011 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3012 * MSGs to all child processes
3014 messaging_deregister(smbd_messaging_context(),
3016 messaging_register(smbd_messaging_context(), NULL,
3017 MSG_DEBUG, debug_message);
3019 if ((lp_keepalive() != 0)
3020 && !(event_add_idle(smbd_event_context(), NULL,
3021 timeval_set(lp_keepalive(), 0),
3022 "keepalive", keepalive_fn,
3024 DEBUG(0, ("Could not add keepalive event\n"));
3028 if (!(event_add_idle(smbd_event_context(), NULL,
3029 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3030 "deadtime", deadtime_fn, NULL))) {
3031 DEBUG(0, ("Could not add deadtime event\n"));
3035 if (!(event_add_idle(smbd_event_context(), NULL,
3036 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3037 "housekeeping", housekeeping_fn, NULL))) {
3038 DEBUG(0, ("Could not add housekeeping event\n"));
3042 #ifdef CLUSTER_SUPPORT
3044 if (lp_clustering()) {
3046 * We need to tell ctdb about our client's TCP
3047 * connection, so that for failover ctdbd can send
3048 * tickle acks, triggering a reconnection by the
3052 struct sockaddr_storage srv, clnt;
3054 if (client_get_tcp_info(&srv, &clnt) == 0) {
3058 status = ctdbd_register_ips(
3059 messaging_ctdbd_connection(),
3060 &srv, &clnt, release_ip, NULL);
3062 if (!NT_STATUS_IS_OK(status)) {
3063 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3064 nt_errstr(status)));
3068 DEBUG(0,("Unable to get tcp info for "
3069 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3076 smbd_server_conn->nbt.got_session = false;
3078 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3080 smbd_server_conn->smb1.sessions.done_sesssetup = false;
3081 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
3082 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3083 /* users from session setup */
3084 smbd_server_conn->smb1.sessions.session_userlist = NULL;
3085 /* workgroup from session setup. */
3086 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
3087 /* this holds info on user ids that are already validated for this VC */
3088 smbd_server_conn->smb1.sessions.validated_users = NULL;
3089 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
3090 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
3092 conn_init(smbd_server_conn);
3093 if (!init_dptrs(smbd_server_conn)) {
3094 exit_server("init_dptrs() failed");
3097 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
3101 smbd_server_connection_handler,
3103 if (!smbd_server_conn->smb1.fde) {
3104 exit_server("failed to create smbd_server_connection fde");
3112 frame = talloc_stackframe_pool(8192);
3116 status = smbd_server_connection_loop_once(smbd_server_conn);
3117 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3118 !NT_STATUS_IS_OK(status)) {
3119 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3120 " exiting\n", nt_errstr(status)));
3127 exit_server_cleanly(NULL);
3130 bool req_is_in_chain(struct smb_request *req)
3132 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3134 * We're right now handling a subsequent request, so we must
3140 if (!is_andx_req(req->cmd)) {
3146 * Okay, an illegal request, but definitely not chained :-)
3151 return (CVAL(req->vwv+0, 0) != 0xFF);