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;
468 req->conn = conn_find(sconn,req->tid);
469 req->chain_fsp = NULL;
470 req->chain_outbuf = NULL;
473 smb_init_perfcount_data(&req->pcd);
475 /* Ensure we have at least wct words and 2 bytes of bcc. */
476 if (smb_size + req->wct*2 > req_size) {
477 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
478 (unsigned int)req->wct,
479 (unsigned int)req_size));
482 /* Ensure bcc is correct. */
483 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
484 DEBUG(0,("init_smb_request: invalid bcc number %u "
485 "(wct = %u, size %u)\n",
486 (unsigned int)req->buflen,
487 (unsigned int)req->wct,
488 (unsigned int)req_size));
496 static void process_smb(struct smbd_server_connection *conn,
497 uint8_t *inbuf, size_t nread, size_t unread_bytes,
498 uint32_t seqnum, bool encrypted,
499 struct smb_perfcount_data *deferred_pcd);
501 static void smbd_deferred_open_timer(struct event_context *ev,
502 struct timed_event *te,
503 struct timeval _tval,
506 struct pending_message_list *msg = talloc_get_type(private_data,
507 struct pending_message_list);
508 TALLOC_CTX *mem_ctx = talloc_tos();
509 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
512 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
515 exit_server("smbd_deferred_open_timer: talloc failed\n");
519 /* We leave this message on the queue so the open code can
520 know this is a retry. */
521 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
522 (unsigned long long)mid ));
524 /* Mark the message as processed so this is not
525 * re-processed in error. */
526 msg->processed = true;
528 process_smb(smbd_server_conn, inbuf,
530 msg->seqnum, msg->encrypted, &msg->pcd);
532 /* If it's still there and was processed, remove it. */
533 msg = get_deferred_open_message_smb(mid);
534 if (msg && msg->processed) {
535 remove_deferred_open_message_smb(mid);
539 /****************************************************************************
540 Function to push a message onto the tail of a linked list of smb messages ready
542 ****************************************************************************/
544 static bool push_queued_message(struct smb_request *req,
545 struct timeval request_time,
546 struct timeval end_time,
547 char *private_data, size_t private_len)
549 int msg_len = smb_len(req->inbuf) + 4;
550 struct pending_message_list *msg;
552 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
555 DEBUG(0,("push_message: malloc fail (1)\n"));
559 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
560 if(msg->buf.data == NULL) {
561 DEBUG(0,("push_message: malloc fail (2)\n"));
566 msg->request_time = request_time;
567 msg->seqnum = req->seqnum;
568 msg->encrypted = req->encrypted;
569 msg->processed = false;
570 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
573 msg->private_data = data_blob_talloc(msg, private_data,
575 if (msg->private_data.data == NULL) {
576 DEBUG(0,("push_message: malloc fail (3)\n"));
582 msg->te = event_add_timed(smbd_event_context(),
585 smbd_deferred_open_timer,
588 DEBUG(0,("push_message: event_add_timed failed\n"));
593 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
595 DEBUG(10,("push_message: pushed message length %u on "
596 "deferred_open_queue\n", (unsigned int)msg_len));
601 /****************************************************************************
602 Function to delete a sharing violation open message by mid.
603 ****************************************************************************/
605 void remove_deferred_open_message_smb(uint64_t mid)
607 struct pending_message_list *pml;
609 if (smbd_server_conn->using_smb2) {
610 remove_deferred_open_message_smb2(mid);
614 for (pml = deferred_open_queue; pml; pml = pml->next) {
615 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
616 DEBUG(10,("remove_deferred_open_message_smb: "
617 "deleting mid %llu len %u\n",
618 (unsigned long long)mid,
619 (unsigned int)pml->buf.length ));
620 DLIST_REMOVE(deferred_open_queue, pml);
627 /****************************************************************************
628 Move a sharing violation open retry message to the front of the list and
629 schedule it for immediate processing.
630 ****************************************************************************/
632 void schedule_deferred_open_message_smb(uint64_t mid)
634 struct pending_message_list *pml;
637 if (smbd_server_conn->using_smb2) {
638 schedule_deferred_open_message_smb2(mid);
642 for (pml = deferred_open_queue; pml; pml = pml->next) {
643 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
645 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
648 (unsigned long long)msg_mid ));
650 if (mid == msg_mid) {
651 struct timed_event *te;
653 if (pml->processed) {
654 /* A processed message should not be
656 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
657 "message mid %llu was already processed\n",
658 (unsigned long long)msg_mid ));
662 DEBUG(10,("schedule_deferred_open_message_smb: "
663 "scheduling mid %llu\n",
664 (unsigned long long)mid ));
666 te = event_add_timed(smbd_event_context(),
669 smbd_deferred_open_timer,
672 DEBUG(10,("schedule_deferred_open_message_smb: "
673 "event_add_timed() failed, "
674 "skipping mid %llu\n",
675 (unsigned long long)msg_mid ));
678 TALLOC_FREE(pml->te);
680 DLIST_PROMOTE(deferred_open_queue, pml);
685 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
686 "find message mid %llu\n",
687 (unsigned long long)mid ));
690 /****************************************************************************
691 Return true if this mid is on the deferred queue and was not yet processed.
692 ****************************************************************************/
694 bool open_was_deferred(uint64_t mid)
696 struct pending_message_list *pml;
698 if (smbd_server_conn->using_smb2) {
699 return open_was_deferred_smb2(mid);
702 for (pml = deferred_open_queue; pml; pml = pml->next) {
703 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
710 /****************************************************************************
711 Return the message queued by this mid.
712 ****************************************************************************/
714 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
716 struct pending_message_list *pml;
718 for (pml = deferred_open_queue; pml; pml = pml->next) {
719 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
726 /****************************************************************************
727 Get the state data queued by this mid.
728 ****************************************************************************/
730 bool get_deferred_open_message_state(struct smb_request *smbreq,
731 struct timeval *p_request_time,
734 struct pending_message_list *pml;
736 if (smbd_server_conn->using_smb2) {
737 return get_deferred_open_message_state_smb2(smbreq->smb2req,
742 pml = get_deferred_open_message_smb(smbreq->mid);
746 if (p_request_time) {
747 *p_request_time = pml->request_time;
750 *pp_state = (void *)pml->private_data.data;
755 /****************************************************************************
756 Function to push a deferred open smb message onto a linked list of local smb
757 messages ready for processing.
758 ****************************************************************************/
760 bool push_deferred_open_message_smb(struct smb_request *req,
761 struct timeval request_time,
762 struct timeval timeout,
764 char *private_data, size_t priv_len)
766 struct timeval end_time;
769 return push_deferred_open_message_smb2(req->smb2req,
777 if (req->unread_bytes) {
778 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
779 "unread_bytes = %u\n",
780 (unsigned int)req->unread_bytes ));
781 smb_panic("push_deferred_open_message_smb: "
782 "logic error unread_bytes != 0" );
785 end_time = timeval_sum(&request_time, &timeout);
787 DEBUG(10,("push_deferred_open_message_smb: pushing message "
788 "len %u mid %llu timeout time [%u.%06u]\n",
789 (unsigned int) smb_len(req->inbuf)+4,
790 (unsigned long long)req->mid,
791 (unsigned int)end_time.tv_sec,
792 (unsigned int)end_time.tv_usec));
794 return push_queued_message(req, request_time, end_time,
795 private_data, priv_len);
799 struct timed_event *te;
800 struct timeval interval;
802 bool (*handler)(const struct timeval *now, void *private_data);
806 static void smbd_idle_event_handler(struct event_context *ctx,
807 struct timed_event *te,
811 struct idle_event *event =
812 talloc_get_type_abort(private_data, struct idle_event);
814 TALLOC_FREE(event->te);
816 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
817 event->name, event->te));
819 if (!event->handler(&now, event->private_data)) {
820 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
821 event->name, event->te));
822 /* Don't repeat, delete ourselves */
827 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
828 event->name, event->te));
830 event->te = event_add_timed(ctx, event,
831 timeval_sum(&now, &event->interval),
832 smbd_idle_event_handler, event);
834 /* We can't do much but fail here. */
835 SMB_ASSERT(event->te != NULL);
838 struct idle_event *event_add_idle(struct event_context *event_ctx,
840 struct timeval interval,
842 bool (*handler)(const struct timeval *now,
846 struct idle_event *result;
847 struct timeval now = timeval_current();
849 result = TALLOC_P(mem_ctx, struct idle_event);
850 if (result == NULL) {
851 DEBUG(0, ("talloc failed\n"));
855 result->interval = interval;
856 result->handler = handler;
857 result->private_data = private_data;
859 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
860 DEBUG(0, ("talloc failed\n"));
865 result->te = event_add_timed(event_ctx, result,
866 timeval_sum(&now, &interval),
867 smbd_idle_event_handler, result);
868 if (result->te == NULL) {
869 DEBUG(0, ("event_add_timed failed\n"));
874 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
878 static void smbd_sig_term_handler(struct tevent_context *ev,
879 struct tevent_signal *se,
885 exit_server_cleanly("termination signal");
888 void smbd_setup_sig_term_handler(void)
890 struct tevent_signal *se;
892 se = tevent_add_signal(smbd_event_context(),
893 smbd_event_context(),
895 smbd_sig_term_handler,
898 exit_server("failed to setup SIGTERM handler");
902 static void smbd_sig_hup_handler(struct tevent_context *ev,
903 struct tevent_signal *se,
909 change_to_root_user();
910 DEBUG(1,("Reloading services after SIGHUP\n"));
911 reload_services(False);
914 void smbd_setup_sig_hup_handler(void)
916 struct tevent_signal *se;
918 se = tevent_add_signal(smbd_event_context(),
919 smbd_event_context(),
921 smbd_sig_hup_handler,
924 exit_server("failed to setup SIGHUP handler");
928 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
935 to.tv_sec = SMBD_SELECT_TIMEOUT;
939 * Setup the select fd sets.
946 * Are there any timed events waiting ? If so, ensure we don't
947 * select for longer than it would take to wait for them.
954 event_add_to_select_args(smbd_event_context(), &now,
955 &r_fds, &w_fds, &to, &maxfd);
958 /* Process a signal and timed events now... */
959 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
960 return NT_STATUS_RETRY;
965 START_PROFILE(smbd_idle);
967 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
970 END_PROFILE(smbd_idle);
974 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
975 return NT_STATUS_RETRY;
980 /* something is wrong. Maybe the socket is dead? */
981 return map_nt_error_from_unix(errno);
984 /* Did we timeout ? */
986 return NT_STATUS_RETRY;
989 /* should not be reached */
990 return NT_STATUS_INTERNAL_ERROR;
994 * Only allow 5 outstanding trans requests. We're allocating memory, so
998 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1001 for (; list != NULL; list = list->next) {
1003 if (list->mid == mid) {
1004 return NT_STATUS_INVALID_PARAMETER;
1010 return NT_STATUS_INSUFFICIENT_RESOURCES;
1013 return NT_STATUS_OK;
1017 These flags determine some of the permissions required to do an operation
1019 Note that I don't set NEED_WRITE on some write operations because they
1020 are used by some brain-dead clients when printing, and I don't want to
1021 force write permissions on print services.
1023 #define AS_USER (1<<0)
1024 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1025 #define TIME_INIT (1<<2)
1026 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1027 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1028 #define DO_CHDIR (1<<6)
1031 define a list of possible SMB messages and their corresponding
1032 functions. Any message that has a NULL function is unimplemented -
1033 please feel free to contribute implementations!
1035 static const struct smb_message_struct {
1037 void (*fn)(struct smb_request *req);
1039 } smb_messages[256] = {
1041 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1042 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1043 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1044 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1045 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1046 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1047 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1048 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1049 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1050 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1051 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1052 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1053 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1054 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1055 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1056 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1057 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1058 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1059 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1060 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1061 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1062 /* 0x15 */ { NULL, NULL, 0 },
1063 /* 0x16 */ { NULL, NULL, 0 },
1064 /* 0x17 */ { NULL, NULL, 0 },
1065 /* 0x18 */ { NULL, NULL, 0 },
1066 /* 0x19 */ { NULL, NULL, 0 },
1067 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1068 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1069 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1070 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1071 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1072 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1073 /* 0x20 */ { "SMBwritec", NULL,0},
1074 /* 0x21 */ { NULL, NULL, 0 },
1075 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1076 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1077 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1078 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1079 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1080 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1081 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1082 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1083 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1084 /* 0x2b */ { "SMBecho",reply_echo,0},
1085 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1086 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1087 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1088 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1089 /* 0x30 */ { NULL, NULL, 0 },
1090 /* 0x31 */ { NULL, NULL, 0 },
1091 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1092 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1093 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1094 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1095 /* 0x36 */ { NULL, NULL, 0 },
1096 /* 0x37 */ { NULL, NULL, 0 },
1097 /* 0x38 */ { NULL, NULL, 0 },
1098 /* 0x39 */ { NULL, NULL, 0 },
1099 /* 0x3a */ { NULL, NULL, 0 },
1100 /* 0x3b */ { NULL, NULL, 0 },
1101 /* 0x3c */ { NULL, NULL, 0 },
1102 /* 0x3d */ { NULL, NULL, 0 },
1103 /* 0x3e */ { NULL, NULL, 0 },
1104 /* 0x3f */ { NULL, NULL, 0 },
1105 /* 0x40 */ { NULL, NULL, 0 },
1106 /* 0x41 */ { NULL, NULL, 0 },
1107 /* 0x42 */ { NULL, NULL, 0 },
1108 /* 0x43 */ { NULL, NULL, 0 },
1109 /* 0x44 */ { NULL, NULL, 0 },
1110 /* 0x45 */ { NULL, NULL, 0 },
1111 /* 0x46 */ { NULL, NULL, 0 },
1112 /* 0x47 */ { NULL, NULL, 0 },
1113 /* 0x48 */ { NULL, NULL, 0 },
1114 /* 0x49 */ { NULL, NULL, 0 },
1115 /* 0x4a */ { NULL, NULL, 0 },
1116 /* 0x4b */ { NULL, NULL, 0 },
1117 /* 0x4c */ { NULL, NULL, 0 },
1118 /* 0x4d */ { NULL, NULL, 0 },
1119 /* 0x4e */ { NULL, NULL, 0 },
1120 /* 0x4f */ { NULL, NULL, 0 },
1121 /* 0x50 */ { NULL, NULL, 0 },
1122 /* 0x51 */ { NULL, NULL, 0 },
1123 /* 0x52 */ { NULL, NULL, 0 },
1124 /* 0x53 */ { NULL, NULL, 0 },
1125 /* 0x54 */ { NULL, NULL, 0 },
1126 /* 0x55 */ { NULL, NULL, 0 },
1127 /* 0x56 */ { NULL, NULL, 0 },
1128 /* 0x57 */ { NULL, NULL, 0 },
1129 /* 0x58 */ { NULL, NULL, 0 },
1130 /* 0x59 */ { NULL, NULL, 0 },
1131 /* 0x5a */ { NULL, NULL, 0 },
1132 /* 0x5b */ { NULL, NULL, 0 },
1133 /* 0x5c */ { NULL, NULL, 0 },
1134 /* 0x5d */ { NULL, NULL, 0 },
1135 /* 0x5e */ { NULL, NULL, 0 },
1136 /* 0x5f */ { NULL, NULL, 0 },
1137 /* 0x60 */ { NULL, NULL, 0 },
1138 /* 0x61 */ { NULL, NULL, 0 },
1139 /* 0x62 */ { NULL, NULL, 0 },
1140 /* 0x63 */ { NULL, NULL, 0 },
1141 /* 0x64 */ { NULL, NULL, 0 },
1142 /* 0x65 */ { NULL, NULL, 0 },
1143 /* 0x66 */ { NULL, NULL, 0 },
1144 /* 0x67 */ { NULL, NULL, 0 },
1145 /* 0x68 */ { NULL, NULL, 0 },
1146 /* 0x69 */ { NULL, NULL, 0 },
1147 /* 0x6a */ { NULL, NULL, 0 },
1148 /* 0x6b */ { NULL, NULL, 0 },
1149 /* 0x6c */ { NULL, NULL, 0 },
1150 /* 0x6d */ { NULL, NULL, 0 },
1151 /* 0x6e */ { NULL, NULL, 0 },
1152 /* 0x6f */ { NULL, NULL, 0 },
1153 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1154 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1155 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1156 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1157 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1158 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1159 /* 0x76 */ { NULL, NULL, 0 },
1160 /* 0x77 */ { NULL, NULL, 0 },
1161 /* 0x78 */ { NULL, NULL, 0 },
1162 /* 0x79 */ { NULL, NULL, 0 },
1163 /* 0x7a */ { NULL, NULL, 0 },
1164 /* 0x7b */ { NULL, NULL, 0 },
1165 /* 0x7c */ { NULL, NULL, 0 },
1166 /* 0x7d */ { NULL, NULL, 0 },
1167 /* 0x7e */ { NULL, NULL, 0 },
1168 /* 0x7f */ { NULL, NULL, 0 },
1169 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1170 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1171 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1172 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1173 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1174 /* 0x85 */ { NULL, NULL, 0 },
1175 /* 0x86 */ { NULL, NULL, 0 },
1176 /* 0x87 */ { NULL, NULL, 0 },
1177 /* 0x88 */ { NULL, NULL, 0 },
1178 /* 0x89 */ { NULL, NULL, 0 },
1179 /* 0x8a */ { NULL, NULL, 0 },
1180 /* 0x8b */ { NULL, NULL, 0 },
1181 /* 0x8c */ { NULL, NULL, 0 },
1182 /* 0x8d */ { NULL, NULL, 0 },
1183 /* 0x8e */ { NULL, NULL, 0 },
1184 /* 0x8f */ { NULL, NULL, 0 },
1185 /* 0x90 */ { NULL, NULL, 0 },
1186 /* 0x91 */ { NULL, NULL, 0 },
1187 /* 0x92 */ { NULL, NULL, 0 },
1188 /* 0x93 */ { NULL, NULL, 0 },
1189 /* 0x94 */ { NULL, NULL, 0 },
1190 /* 0x95 */ { NULL, NULL, 0 },
1191 /* 0x96 */ { NULL, NULL, 0 },
1192 /* 0x97 */ { NULL, NULL, 0 },
1193 /* 0x98 */ { NULL, NULL, 0 },
1194 /* 0x99 */ { NULL, NULL, 0 },
1195 /* 0x9a */ { NULL, NULL, 0 },
1196 /* 0x9b */ { NULL, NULL, 0 },
1197 /* 0x9c */ { NULL, NULL, 0 },
1198 /* 0x9d */ { NULL, NULL, 0 },
1199 /* 0x9e */ { NULL, NULL, 0 },
1200 /* 0x9f */ { NULL, NULL, 0 },
1201 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1202 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1203 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1204 /* 0xa3 */ { NULL, NULL, 0 },
1205 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1206 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1207 /* 0xa6 */ { NULL, NULL, 0 },
1208 /* 0xa7 */ { NULL, NULL, 0 },
1209 /* 0xa8 */ { NULL, NULL, 0 },
1210 /* 0xa9 */ { NULL, NULL, 0 },
1211 /* 0xaa */ { NULL, NULL, 0 },
1212 /* 0xab */ { NULL, NULL, 0 },
1213 /* 0xac */ { NULL, NULL, 0 },
1214 /* 0xad */ { NULL, NULL, 0 },
1215 /* 0xae */ { NULL, NULL, 0 },
1216 /* 0xaf */ { NULL, NULL, 0 },
1217 /* 0xb0 */ { NULL, NULL, 0 },
1218 /* 0xb1 */ { NULL, NULL, 0 },
1219 /* 0xb2 */ { NULL, NULL, 0 },
1220 /* 0xb3 */ { NULL, NULL, 0 },
1221 /* 0xb4 */ { NULL, NULL, 0 },
1222 /* 0xb5 */ { NULL, NULL, 0 },
1223 /* 0xb6 */ { NULL, NULL, 0 },
1224 /* 0xb7 */ { NULL, NULL, 0 },
1225 /* 0xb8 */ { NULL, NULL, 0 },
1226 /* 0xb9 */ { NULL, NULL, 0 },
1227 /* 0xba */ { NULL, NULL, 0 },
1228 /* 0xbb */ { NULL, NULL, 0 },
1229 /* 0xbc */ { NULL, NULL, 0 },
1230 /* 0xbd */ { NULL, NULL, 0 },
1231 /* 0xbe */ { NULL, NULL, 0 },
1232 /* 0xbf */ { NULL, NULL, 0 },
1233 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1234 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1235 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1236 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1237 /* 0xc4 */ { NULL, NULL, 0 },
1238 /* 0xc5 */ { NULL, NULL, 0 },
1239 /* 0xc6 */ { NULL, NULL, 0 },
1240 /* 0xc7 */ { NULL, NULL, 0 },
1241 /* 0xc8 */ { NULL, NULL, 0 },
1242 /* 0xc9 */ { NULL, NULL, 0 },
1243 /* 0xca */ { NULL, NULL, 0 },
1244 /* 0xcb */ { NULL, NULL, 0 },
1245 /* 0xcc */ { NULL, NULL, 0 },
1246 /* 0xcd */ { NULL, NULL, 0 },
1247 /* 0xce */ { NULL, NULL, 0 },
1248 /* 0xcf */ { NULL, NULL, 0 },
1249 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1250 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1251 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1252 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1253 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1254 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1255 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1256 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1257 /* 0xd8 */ { NULL, NULL, 0 },
1258 /* 0xd9 */ { NULL, NULL, 0 },
1259 /* 0xda */ { NULL, NULL, 0 },
1260 /* 0xdb */ { NULL, NULL, 0 },
1261 /* 0xdc */ { NULL, NULL, 0 },
1262 /* 0xdd */ { NULL, NULL, 0 },
1263 /* 0xde */ { NULL, NULL, 0 },
1264 /* 0xdf */ { NULL, NULL, 0 },
1265 /* 0xe0 */ { NULL, NULL, 0 },
1266 /* 0xe1 */ { NULL, NULL, 0 },
1267 /* 0xe2 */ { NULL, NULL, 0 },
1268 /* 0xe3 */ { NULL, NULL, 0 },
1269 /* 0xe4 */ { NULL, NULL, 0 },
1270 /* 0xe5 */ { NULL, NULL, 0 },
1271 /* 0xe6 */ { NULL, NULL, 0 },
1272 /* 0xe7 */ { NULL, NULL, 0 },
1273 /* 0xe8 */ { NULL, NULL, 0 },
1274 /* 0xe9 */ { NULL, NULL, 0 },
1275 /* 0xea */ { NULL, NULL, 0 },
1276 /* 0xeb */ { NULL, NULL, 0 },
1277 /* 0xec */ { NULL, NULL, 0 },
1278 /* 0xed */ { NULL, NULL, 0 },
1279 /* 0xee */ { NULL, NULL, 0 },
1280 /* 0xef */ { NULL, NULL, 0 },
1281 /* 0xf0 */ { NULL, NULL, 0 },
1282 /* 0xf1 */ { NULL, NULL, 0 },
1283 /* 0xf2 */ { NULL, NULL, 0 },
1284 /* 0xf3 */ { NULL, NULL, 0 },
1285 /* 0xf4 */ { NULL, NULL, 0 },
1286 /* 0xf5 */ { NULL, NULL, 0 },
1287 /* 0xf6 */ { NULL, NULL, 0 },
1288 /* 0xf7 */ { NULL, NULL, 0 },
1289 /* 0xf8 */ { NULL, NULL, 0 },
1290 /* 0xf9 */ { NULL, NULL, 0 },
1291 /* 0xfa */ { NULL, NULL, 0 },
1292 /* 0xfb */ { NULL, NULL, 0 },
1293 /* 0xfc */ { NULL, NULL, 0 },
1294 /* 0xfd */ { NULL, NULL, 0 },
1295 /* 0xfe */ { NULL, NULL, 0 },
1296 /* 0xff */ { NULL, NULL, 0 }
1300 /*******************************************************************
1301 allocate and initialize a reply packet
1302 ********************************************************************/
1304 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1305 const char *inbuf, char **outbuf, uint8_t num_words,
1309 * Protect against integer wrap
1311 if ((num_bytes > 0xffffff)
1312 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1314 if (asprintf(&msg, "num_bytes too large: %u",
1315 (unsigned)num_bytes) == -1) {
1316 msg = CONST_DISCARD(char *, "num_bytes too large");
1321 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1322 smb_size + num_words*2 + num_bytes);
1323 if (*outbuf == NULL) {
1327 construct_reply_common(req, inbuf, *outbuf);
1328 srv_set_message(*outbuf, num_words, num_bytes, false);
1330 * Zero out the word area, the caller has to take care of the bcc area
1333 if (num_words != 0) {
1334 memset(*outbuf + smb_vwv0, 0, num_words*2);
1340 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1343 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1345 smb_panic("could not allocate output buffer\n");
1347 req->outbuf = (uint8_t *)outbuf;
1351 /*******************************************************************
1352 Dump a packet to a file.
1353 ********************************************************************/
1355 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1359 if (DEBUGLEVEL < 50) {
1363 if (len < 4) len = smb_len(data)+4;
1364 for (i=1;i<100;i++) {
1365 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1366 type ? "req" : "resp") == -1) {
1369 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1370 if (fd != -1 || errno != EEXIST) break;
1373 ssize_t ret = write(fd, data, len);
1375 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1377 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1382 /****************************************************************************
1383 Prepare everything for calling the actual request function, and potentially
1384 call the request function via the "new" interface.
1386 Return False if the "legacy" function needs to be called, everything is
1389 Return True if we're done.
1391 I know this API sucks, but it is the one with the least code change I could
1393 ****************************************************************************/
1395 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1399 connection_struct *conn = NULL;
1400 struct smbd_server_connection *sconn = smbd_server_conn;
1404 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1405 * so subtract 4 from it. */
1406 if (!valid_smb_header(req->inbuf)
1407 || (size < (smb_size - 4))) {
1408 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1409 smb_len(req->inbuf)));
1410 exit_server_cleanly("Non-SMB packet");
1413 if (smb_messages[type].fn == NULL) {
1414 DEBUG(0,("Unknown message type %d!\n",type));
1415 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1416 reply_unknown_new(req, type);
1420 flags = smb_messages[type].flags;
1422 /* In share mode security we must ignore the vuid. */
1423 session_tag = (lp_security() == SEC_SHARE)
1424 ? UID_FIELD_INVALID : req->vuid;
1427 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1428 (int)sys_getpid(), (unsigned long)conn));
1430 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1432 /* Ensure this value is replaced in the incoming packet. */
1433 SSVAL(req->inbuf,smb_uid,session_tag);
1436 * Ensure the correct username is in current_user_info. This is a
1437 * really ugly bugfix for problems with multiple session_setup_and_X's
1438 * being done and allowing %U and %G substitutions to work correctly.
1439 * There is a reason this code is done here, don't move it unless you
1440 * know what you're doing... :-).
1444 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1445 user_struct *vuser = NULL;
1447 sconn->smb1.sessions.last_session_tag = session_tag;
1448 if(session_tag != UID_FIELD_INVALID) {
1449 vuser = get_valid_user_struct(sconn, session_tag);
1451 set_current_user_info(
1452 vuser->server_info->sanitized_username,
1453 vuser->server_info->unix_name,
1454 vuser->server_info->info3->base.domain.string);
1459 /* Does this call need to be run as the connected user? */
1460 if (flags & AS_USER) {
1462 /* Does this call need a valid tree connection? */
1465 * Amazingly, the error code depends on the command
1468 if (type == SMBntcreateX) {
1469 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1471 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1476 if (!change_to_user(conn,session_tag)) {
1477 DEBUG(0, ("Error: Could not change to user. Removing "
1478 "deferred open, mid=%llu.\n",
1479 (unsigned long long)req->mid));
1480 reply_force_doserror(req, ERRSRV, ERRbaduid);
1484 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1486 /* Does it need write permission? */
1487 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1488 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1492 /* IPC services are limited */
1493 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1494 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1498 /* This call needs to be run as root */
1499 change_to_root_user();
1502 /* load service specific parameters */
1504 if (req->encrypted) {
1505 conn->encrypted_tid = true;
1506 /* encrypted required from now on. */
1507 conn->encrypt_level = Required;
1508 } else if (ENCRYPTION_REQUIRED(conn)) {
1509 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1510 exit_server_cleanly("encryption required "
1516 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1517 (flags & (AS_USER|DO_CHDIR)
1519 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1522 conn->num_smb_operations++;
1525 /* does this protocol need to be run as guest? */
1526 if ((flags & AS_GUEST)
1527 && (!change_to_guest() ||
1528 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1529 lp_hostsdeny(-1)))) {
1530 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1534 smb_messages[type].fn(req);
1538 /****************************************************************************
1539 Construct a reply to the incoming packet.
1540 ****************************************************************************/
1542 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1543 uint32_t seqnum, bool encrypted,
1544 struct smb_perfcount_data *deferred_pcd)
1546 connection_struct *conn;
1547 struct smb_request *req;
1549 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1550 smb_panic("could not allocate smb_request");
1553 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1555 exit_server_cleanly("Invalid SMB request");
1558 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1560 /* we popped this message off the queue - keep original perf data */
1562 req->pcd = *deferred_pcd;
1564 SMB_PERFCOUNT_START(&req->pcd);
1565 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1566 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1569 conn = switch_message(req->cmd, req, size);
1571 if (req->unread_bytes) {
1572 /* writeX failed. drain socket. */
1573 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1574 req->unread_bytes) {
1575 smb_panic("failed to drain pending bytes");
1577 req->unread_bytes = 0;
1585 if (req->outbuf == NULL) {
1589 if (CVAL(req->outbuf,0) == 0) {
1590 show_msg((char *)req->outbuf);
1593 if (!srv_send_smb(smbd_server_fd(),
1594 (char *)req->outbuf,
1595 true, req->seqnum+1,
1596 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1598 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1606 /****************************************************************************
1607 Process an smb from the client
1608 ****************************************************************************/
1609 static void process_smb(struct smbd_server_connection *conn,
1610 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1611 uint32_t seqnum, bool encrypted,
1612 struct smb_perfcount_data *deferred_pcd)
1614 int msg_type = CVAL(inbuf,0);
1616 DO_PROFILE_INC(smb_count);
1618 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1620 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1622 (unsigned int)unread_bytes ));
1624 if (msg_type != 0) {
1626 * NetBIOS session request, keepalive, etc.
1628 reply_special((char *)inbuf);
1632 if (smbd_server_conn->using_smb2) {
1633 /* At this point we're not really using smb2,
1634 * we make the decision here.. */
1635 if (smbd_is_smb2_header(inbuf, nread)) {
1636 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1638 } else if (nread >= smb_size && valid_smb_header(inbuf)
1639 && CVAL(inbuf, smb_com) != 0x72) {
1640 /* This is a non-negprot SMB1 packet.
1641 Disable SMB2 from now on. */
1642 smbd_server_conn->using_smb2 = false;
1646 show_msg((char *)inbuf);
1648 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1652 conn->smb1.num_requests++;
1654 /* The timeout_processing function isn't run nearly
1655 often enough to implement 'max log size' without
1656 overrunning the size of the file by many megabytes.
1657 This is especially true if we are running at debug
1658 level 10. Checking every 50 SMBs is a nice
1659 tradeoff of performance vs log file size overrun. */
1661 if ((conn->smb1.num_requests % 50) == 0 &&
1662 need_to_check_log_size()) {
1663 change_to_root_user();
1668 /****************************************************************************
1669 Return a string containing the function name of a SMB command.
1670 ****************************************************************************/
1672 const char *smb_fn_name(int type)
1674 const char *unknown_name = "SMBunknown";
1676 if (smb_messages[type].name == NULL)
1677 return(unknown_name);
1679 return(smb_messages[type].name);
1682 /****************************************************************************
1683 Helper functions for contruct_reply.
1684 ****************************************************************************/
1686 void add_to_common_flags2(uint32 v)
1691 void remove_from_common_flags2(uint32 v)
1693 common_flags2 &= ~v;
1696 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1699 srv_set_message(outbuf,0,0,false);
1701 SCVAL(outbuf, smb_com, req->cmd);
1702 SIVAL(outbuf,smb_rcls,0);
1703 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1704 SSVAL(outbuf,smb_flg2,
1705 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1707 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1709 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1710 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1711 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1712 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1715 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1717 construct_reply_common(req, (char *)req->inbuf, outbuf);
1721 * How many bytes have we already accumulated up to the current wct field
1725 size_t req_wct_ofs(struct smb_request *req)
1729 if (req->chain_outbuf == NULL) {
1732 buf_size = talloc_get_size(req->chain_outbuf);
1733 if ((buf_size % 4) != 0) {
1734 buf_size += (4 - (buf_size % 4));
1736 return buf_size - 4;
1740 * Hack around reply_nterror & friends not being aware of chained requests,
1741 * generating illegal (i.e. wct==0) chain replies.
1744 static void fixup_chain_error_packet(struct smb_request *req)
1746 uint8_t *outbuf = req->outbuf;
1748 reply_outbuf(req, 2, 0);
1749 memcpy(req->outbuf, outbuf, smb_wct);
1750 TALLOC_FREE(outbuf);
1751 SCVAL(req->outbuf, smb_vwv0, 0xff);
1755 * @brief Find the smb_cmd offset of the last command pushed
1756 * @param[in] buf The buffer we're building up
1757 * @retval Where can we put our next andx cmd?
1759 * While chaining requests, the "next" request we're looking at needs to put
1760 * its SMB_Command before the data the previous request already built up added
1761 * to the chain. Find the offset to the place where we have to put our cmd.
1764 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1769 cmd = CVAL(buf, smb_com);
1771 SMB_ASSERT(is_andx_req(cmd));
1775 while (CVAL(buf, ofs) != 0xff) {
1777 if (!is_andx_req(CVAL(buf, ofs))) {
1782 * ofs is from start of smb header, so add the 4 length
1783 * bytes. The next cmd is right after the wct field.
1785 ofs = SVAL(buf, ofs+2) + 4 + 1;
1787 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1795 * @brief Do the smb chaining at a buffer level
1796 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1797 * @param[in] smb_command The command that we want to issue
1798 * @param[in] wct How many words?
1799 * @param[in] vwv The words, already in network order
1800 * @param[in] bytes_alignment How shall we align "bytes"?
1801 * @param[in] num_bytes How many bytes?
1802 * @param[in] bytes The data the request ships
1804 * smb_splice_chain() adds the vwv and bytes to the request already present in
1808 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1809 uint8_t wct, const uint16_t *vwv,
1810 size_t bytes_alignment,
1811 uint32_t num_bytes, const uint8_t *bytes)
1814 size_t old_size, new_size;
1816 size_t chain_padding = 0;
1817 size_t bytes_padding = 0;
1820 old_size = talloc_get_size(*poutbuf);
1823 * old_size == smb_wct means we're pushing the first request in for
1827 first_request = (old_size == smb_wct);
1829 if (!first_request && ((old_size % 4) != 0)) {
1831 * Align the wct field of subsequent requests to a 4-byte
1834 chain_padding = 4 - (old_size % 4);
1838 * After the old request comes the new wct field (1 byte), the vwv's
1839 * and the num_bytes field. After at we might need to align the bytes
1840 * given to us to "bytes_alignment", increasing the num_bytes value.
1843 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1845 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1846 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1849 new_size += bytes_padding + num_bytes;
1851 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1852 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1853 (unsigned)new_size));
1857 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1858 if (outbuf == NULL) {
1859 DEBUG(0, ("talloc failed\n"));
1864 if (first_request) {
1865 SCVAL(outbuf, smb_com, smb_command);
1867 size_t andx_cmd_ofs;
1869 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1870 DEBUG(1, ("invalid command chain\n"));
1871 *poutbuf = TALLOC_REALLOC_ARRAY(
1872 NULL, *poutbuf, uint8_t, old_size);
1876 if (chain_padding != 0) {
1877 memset(outbuf + old_size, 0, chain_padding);
1878 old_size += chain_padding;
1881 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1882 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1888 * Push the chained request:
1893 SCVAL(outbuf, ofs, wct);
1900 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1901 ofs += sizeof(uint16_t) * wct;
1907 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1908 ofs += sizeof(uint16_t);
1914 if (bytes_padding != 0) {
1915 memset(outbuf + ofs, 0, bytes_padding);
1916 ofs += bytes_padding;
1923 memcpy(outbuf + ofs, bytes, num_bytes);
1928 /****************************************************************************
1929 Construct a chained reply and add it to the already made reply
1930 ****************************************************************************/
1932 void chain_reply(struct smb_request *req)
1934 size_t smblen = smb_len(req->inbuf);
1935 size_t already_used, length_needed;
1937 uint32_t chain_offset; /* uint32_t to avoid overflow */
1944 if (IVAL(req->outbuf, smb_rcls) != 0) {
1945 fixup_chain_error_packet(req);
1949 * Any of the AndX requests and replies have at least a wct of
1950 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1951 * beginning of the SMB header to the next wct field.
1953 * None of the AndX requests put anything valuable in vwv[0] and [1],
1954 * so we can overwrite it here to form the chain.
1957 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1958 if (req->chain_outbuf == NULL) {
1959 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1960 req, req->outbuf, uint8_t,
1961 smb_len(req->outbuf) + 4);
1962 if (req->chain_outbuf == NULL) {
1963 smb_panic("talloc failed");
1971 * Here we assume that this is the end of the chain. For that we need
1972 * to set "next command" to 0xff and the offset to 0. If we later find
1973 * more commands in the chain, this will be overwritten again.
1976 SCVAL(req->outbuf, smb_vwv0, 0xff);
1977 SCVAL(req->outbuf, smb_vwv0+1, 0);
1978 SSVAL(req->outbuf, smb_vwv1, 0);
1980 if (req->chain_outbuf == NULL) {
1982 * In req->chain_outbuf we collect all the replies. Start the
1983 * chain by copying in the first reply.
1985 * We do the realloc because later on we depend on
1986 * talloc_get_size to determine the length of
1987 * chain_outbuf. The reply_xxx routines might have
1988 * over-allocated (reply_pipe_read_and_X used to be such an
1991 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1992 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1993 if (req->chain_outbuf == NULL) {
1994 smb_panic("talloc failed");
1999 * Update smb headers where subsequent chained commands
2000 * may have updated them.
2002 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2003 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2005 if (!smb_splice_chain(&req->chain_outbuf,
2006 CVAL(req->outbuf, smb_com),
2007 CVAL(req->outbuf, smb_wct),
2008 (uint16_t *)(req->outbuf + smb_vwv),
2009 0, smb_buflen(req->outbuf),
2010 (uint8_t *)smb_buf(req->outbuf))) {
2013 TALLOC_FREE(req->outbuf);
2017 * We use the old request's vwv field to grab the next chained command
2018 * and offset into the chained fields.
2021 chain_cmd = CVAL(req->vwv+0, 0);
2022 chain_offset = SVAL(req->vwv+1, 0);
2024 if (chain_cmd == 0xff) {
2026 * End of chain, no more requests from the client. So ship the
2029 smb_setlen((char *)(req->chain_outbuf),
2030 talloc_get_size(req->chain_outbuf) - 4);
2032 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2033 true, req->seqnum+1,
2034 IS_CONN_ENCRYPTED(req->conn)
2037 exit_server_cleanly("chain_reply: srv_send_smb "
2040 TALLOC_FREE(req->chain_outbuf);
2045 /* add a new perfcounter for this element of chain */
2046 SMB_PERFCOUNT_ADD(&req->pcd);
2047 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2048 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2051 * Check if the client tries to fool us. The request so far uses the
2052 * space to the end of the byte buffer in the request just
2053 * processed. The chain_offset can't point into that area. If that was
2054 * the case, we could end up with an endless processing of the chain,
2055 * we would always handle the same request.
2058 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2059 if (chain_offset < already_used) {
2064 * Next check: Make sure the chain offset does not point beyond the
2065 * overall smb request length.
2068 length_needed = chain_offset+1; /* wct */
2069 if (length_needed > smblen) {
2074 * Now comes the pointer magic. Goal here is to set up req->vwv and
2075 * req->buf correctly again to be able to call the subsequent
2076 * switch_message(). The chain offset (the former vwv[1]) points at
2077 * the new wct field.
2080 wct = CVAL(smb_base(req->inbuf), chain_offset);
2083 * Next consistency check: Make the new vwv array fits in the overall
2087 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2088 if (length_needed > smblen) {
2091 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2094 * Now grab the new byte buffer....
2097 buflen = SVAL(vwv+wct, 0);
2100 * .. and check that it fits.
2103 length_needed += buflen;
2104 if (length_needed > smblen) {
2107 buf = (uint8_t *)(vwv+wct+1);
2109 req->cmd = chain_cmd;
2112 req->buflen = buflen;
2115 switch_message(chain_cmd, req, smblen);
2117 if (req->outbuf == NULL) {
2119 * This happens if the chained command has suspended itself or
2120 * if it has called srv_send_smb() itself.
2126 * We end up here if the chained command was not itself chained or
2127 * suspended, but for example a close() command. We now need to splice
2128 * the chained commands' outbuf into the already built up chain_outbuf
2129 * and ship the result.
2135 * We end up here if there's any error in the chain syntax. Report a
2136 * DOS error, just like Windows does.
2138 reply_force_doserror(req, ERRSRV, ERRerror);
2139 fixup_chain_error_packet(req);
2143 * This scary statement intends to set the
2144 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2145 * to the value req->outbuf carries
2147 SSVAL(req->chain_outbuf, smb_flg2,
2148 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2149 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2152 * Transfer the error codes from the subrequest to the main one
2154 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2155 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2157 if (!smb_splice_chain(&req->chain_outbuf,
2158 CVAL(req->outbuf, smb_com),
2159 CVAL(req->outbuf, smb_wct),
2160 (uint16_t *)(req->outbuf + smb_vwv),
2161 0, smb_buflen(req->outbuf),
2162 (uint8_t *)smb_buf(req->outbuf))) {
2163 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2165 TALLOC_FREE(req->outbuf);
2167 smb_setlen((char *)(req->chain_outbuf),
2168 talloc_get_size(req->chain_outbuf) - 4);
2170 show_msg((char *)(req->chain_outbuf));
2172 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2173 true, req->seqnum+1,
2174 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2176 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2178 TALLOC_FREE(req->chain_outbuf);
2182 /****************************************************************************
2183 Check if services need reloading.
2184 ****************************************************************************/
2186 void check_reload(time_t t)
2188 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2190 if(last_smb_conf_reload_time == 0) {
2191 last_smb_conf_reload_time = t;
2192 /* Our printing subsystem might not be ready at smbd start up.
2193 Then no printer is available till the first printers check
2194 is performed. A lower initial interval circumvents this. */
2195 if ( printcap_cache_time > 60 )
2196 last_printer_reload_time = t - printcap_cache_time + 60;
2198 last_printer_reload_time = t;
2201 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2202 /* randomize over 60 second the printcap reload to avoid all
2203 * process hitting cupsd at the same time */
2204 int time_range = 60;
2206 last_printer_reload_time += random() % time_range;
2210 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2211 reload_services(True);
2212 last_smb_conf_reload_time = t;
2215 /* 'printcap cache time = 0' disable the feature */
2217 if ( printcap_cache_time != 0 )
2219 /* see if it's time to reload or if the clock has been set back */
2221 if ( (t >= last_printer_reload_time+printcap_cache_time)
2222 || (t-last_printer_reload_time < 0) )
2224 DEBUG( 3,( "Printcap cache time expired.\n"));
2226 last_printer_reload_time = t;
2231 static bool fd_is_readable(int fd)
2234 struct timeval timeout = {0, };
2240 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2244 return FD_ISSET(fd, &fds);
2247 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2249 /* TODO: make write nonblocking */
2252 static void smbd_server_connection_read_handler(
2253 struct smbd_server_connection *conn, int fd)
2255 uint8_t *inbuf = NULL;
2256 size_t inbuf_len = 0;
2257 size_t unread_bytes = 0;
2258 bool encrypted = false;
2259 TALLOC_CTX *mem_ctx = talloc_tos();
2263 bool from_client = (smbd_server_fd() == fd)?true:false;
2266 smbd_lock_socket(conn);
2268 if (!fd_is_readable(smbd_server_fd())) {
2269 DEBUG(10,("the echo listener was faster\n"));
2270 smbd_unlock_socket(conn);
2274 /* TODO: make this completely nonblocking */
2275 status = receive_smb_talloc(mem_ctx, fd,
2276 (char **)(void *)&inbuf,
2280 &inbuf_len, &seqnum,
2281 false /* trusted channel */);
2282 smbd_unlock_socket(conn);
2284 /* TODO: make this completely nonblocking */
2285 status = receive_smb_talloc(mem_ctx, fd,
2286 (char **)(void *)&inbuf,
2290 &inbuf_len, &seqnum,
2291 true /* trusted channel */);
2294 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2297 if (NT_STATUS_IS_ERR(status)) {
2298 exit_server_cleanly("failed to receive smb request");
2300 if (!NT_STATUS_IS_OK(status)) {
2305 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2306 seqnum, encrypted, NULL);
2309 static void smbd_server_connection_handler(struct event_context *ev,
2310 struct fd_event *fde,
2314 struct smbd_server_connection *conn = talloc_get_type(private_data,
2315 struct smbd_server_connection);
2317 if (flags & EVENT_FD_WRITE) {
2318 smbd_server_connection_write_handler(conn);
2319 } else if (flags & EVENT_FD_READ) {
2320 smbd_server_connection_read_handler(conn, smbd_server_fd());
2324 static void smbd_server_echo_handler(struct event_context *ev,
2325 struct fd_event *fde,
2329 struct smbd_server_connection *conn = talloc_get_type(private_data,
2330 struct smbd_server_connection);
2332 if (flags & EVENT_FD_WRITE) {
2333 smbd_server_connection_write_handler(conn);
2334 } else if (flags & EVENT_FD_READ) {
2335 smbd_server_connection_read_handler(
2336 conn, conn->smb1.echo_handler.trusted_fd);
2340 /****************************************************************************
2341 received when we should release a specific IP
2342 ****************************************************************************/
2343 static void release_ip(const char *ip, void *priv)
2345 char addr[INET6_ADDRSTRLEN];
2348 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2350 if (strncmp("::ffff:", addr, 7) == 0) {
2354 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2355 /* we can't afford to do a clean exit - that involves
2356 database writes, which would potentially mean we
2357 are still running after the failover has finished -
2358 we have to get rid of this process ID straight
2360 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2362 /* note we must exit with non-zero status so the unclean handler gets
2363 called in the parent, so that the brl database is tickled */
2368 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2369 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2371 release_ip((char *)data->data, NULL);
2374 #ifdef CLUSTER_SUPPORT
2375 static int client_get_tcp_info(struct sockaddr_storage *server,
2376 struct sockaddr_storage *client)
2379 if (server_fd == -1) {
2382 length = sizeof(*server);
2383 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2386 length = sizeof(*client);
2387 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2395 * Send keepalive packets to our client
2397 static bool keepalive_fn(const struct timeval *now, void *private_data)
2399 struct smbd_server_connection *sconn = smbd_server_conn;
2402 if (sconn->using_smb2) {
2403 /* Don't do keepalives on an SMB2 connection. */
2407 smbd_lock_socket(smbd_server_conn);
2408 ret = send_keepalive(smbd_server_fd());
2409 smbd_unlock_socket(smbd_server_conn);
2412 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2419 * Do the recurring check if we're idle
2421 static bool deadtime_fn(const struct timeval *now, void *private_data)
2423 struct smbd_server_connection *sconn = smbd_server_conn;
2425 if (sconn->using_smb2) {
2426 /* TODO: implement real idle check */
2427 if (sconn->smb2.sessions.list) {
2430 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2431 messaging_send(smbd_messaging_context(), procid_self(),
2432 MSG_SHUTDOWN, &data_blob_null);
2436 if ((conn_num_open(sconn) == 0)
2437 || (conn_idle_all(sconn, now->tv_sec))) {
2438 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2439 messaging_send(smbd_messaging_context(), procid_self(),
2440 MSG_SHUTDOWN, &data_blob_null);
2448 * Do the recurring log file and smb.conf reload checks.
2451 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2453 change_to_root_user();
2455 /* update printer queue caches if necessary */
2456 update_monitored_printq_cache();
2458 /* check if we need to reload services */
2459 check_reload(time(NULL));
2461 /* Change machine password if neccessary. */
2462 attempt_machine_password_change();
2465 * Force a log file check.
2467 force_check_log_size();
2472 static int create_unlink_tmp(const char *dir)
2477 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2478 if (fname == NULL) {
2482 fd = mkstemp(fname);
2487 if (unlink(fname) == -1) {
2488 int sys_errno = errno;
2498 struct smbd_echo_state {
2499 struct tevent_context *ev;
2500 struct iovec *pending;
2501 struct smbd_server_connection *sconn;
2504 struct tevent_fd *parent_fde;
2506 struct tevent_fd *read_fde;
2507 struct tevent_req *write_req;
2510 static void smbd_echo_writer_done(struct tevent_req *req);
2512 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2516 if (state->write_req != NULL) {
2520 num_pending = talloc_array_length(state->pending);
2521 if (num_pending == 0) {
2525 state->write_req = writev_send(state, state->ev, NULL,
2526 state->parent_pipe, false,
2527 state->pending, num_pending);
2528 if (state->write_req == NULL) {
2529 DEBUG(1, ("writev_send failed\n"));
2533 talloc_steal(state->write_req, state->pending);
2534 state->pending = NULL;
2536 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2540 static void smbd_echo_writer_done(struct tevent_req *req)
2542 struct smbd_echo_state *state = tevent_req_callback_data(
2543 req, struct smbd_echo_state);
2547 written = writev_recv(req, &err);
2549 state->write_req = NULL;
2550 if (written == -1) {
2551 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2554 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2555 smbd_echo_activate_writer(state);
2558 static bool smbd_echo_reply(int fd,
2559 uint8_t *inbuf, size_t inbuf_len,
2562 struct smb_request req;
2563 uint16_t num_replies;
2568 if (inbuf_len < smb_size) {
2569 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2572 if (!valid_smb_header(inbuf)) {
2573 DEBUG(10, ("Got invalid SMB header\n"));
2577 if (!init_smb_request(&req, inbuf, 0, false, seqnum)) {
2582 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2583 smb_messages[req.cmd].name
2584 ? smb_messages[req.cmd].name : "unknown"));
2586 if (req.cmd != SMBecho) {
2593 num_replies = SVAL(req.vwv+0, 0);
2594 if (num_replies != 1) {
2595 /* Not a Windows "Hey, you're still there?" request */
2599 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2601 DEBUG(10, ("create_outbuf failed\n"));
2604 req.outbuf = (uint8_t *)outbuf;
2606 SSVAL(req.outbuf, smb_vwv0, num_replies);
2608 if (req.buflen > 0) {
2609 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2612 out_len = smb_len(req.outbuf) + 4;
2614 ok = srv_send_smb(smbd_server_fd(),
2618 TALLOC_FREE(outbuf);
2626 static void smbd_echo_exit(struct tevent_context *ev,
2627 struct tevent_fd *fde, uint16_t flags,
2630 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2634 static void smbd_echo_reader(struct tevent_context *ev,
2635 struct tevent_fd *fde, uint16_t flags,
2638 struct smbd_echo_state *state = talloc_get_type_abort(
2639 private_data, struct smbd_echo_state);
2640 struct smbd_server_connection *sconn = state->sconn;
2641 size_t unread, num_pending;
2644 uint32_t seqnum = 0;
2647 bool encrypted = false;
2649 ok = smbd_lock_socket_internal(sconn);
2651 DEBUG(0, ("%s: failed to lock socket\n",
2656 if (!fd_is_readable(smbd_server_fd())) {
2657 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2658 (int)sys_getpid()));
2659 ok = smbd_unlock_socket_internal(sconn);
2661 DEBUG(1, ("%s: failed to unlock socket in\n",
2668 num_pending = talloc_array_length(state->pending);
2669 tmp = talloc_realloc(state, state->pending, struct iovec,
2672 DEBUG(1, ("talloc_realloc failed\n"));
2675 state->pending = tmp;
2677 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2679 status = receive_smb_talloc(state->pending, smbd_server_fd(),
2680 (char **)(void *)&state->pending[num_pending].iov_base,
2684 &state->pending[num_pending].iov_len,
2686 false /* trusted_channel*/);
2687 if (!NT_STATUS_IS_OK(status)) {
2688 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2689 (int)sys_getpid(), nt_errstr(status)));
2693 ok = smbd_unlock_socket_internal(sconn);
2695 DEBUG(1, ("%s: failed to unlock socket in\n",
2701 * place the seqnum in the packet so that the main process can reply
2704 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2705 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2707 reply = smbd_echo_reply(smbd_server_fd(),
2708 (uint8_t *)state->pending[num_pending].iov_base,
2709 state->pending[num_pending].iov_len,
2712 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2713 /* no check, shrinking by some bytes does not fail */
2714 state->pending = talloc_realloc(state, state->pending,
2718 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2719 smbd_echo_activate_writer(state);
2723 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2726 struct smbd_echo_state *state;
2728 state = talloc_zero(sconn, struct smbd_echo_state);
2729 if (state == NULL) {
2730 DEBUG(1, ("talloc failed\n"));
2733 state->sconn = sconn;
2734 state->parent_pipe = parent_pipe;
2735 state->ev = s3_tevent_context_init(state);
2736 if (state->ev == NULL) {
2737 DEBUG(1, ("tevent_context_init failed\n"));
2741 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2742 TEVENT_FD_READ, smbd_echo_exit,
2744 if (state->parent_fde == NULL) {
2745 DEBUG(1, ("tevent_add_fd failed\n"));
2749 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2750 TEVENT_FD_READ, smbd_echo_reader,
2752 if (state->read_fde == NULL) {
2753 DEBUG(1, ("tevent_add_fd failed\n"));
2759 if (tevent_loop_once(state->ev) == -1) {
2760 DEBUG(1, ("tevent_loop_once failed: %s\n",
2769 * Handle SMBecho requests in a forked child process
2771 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2773 int listener_pipe[2];
2777 res = pipe(listener_pipe);
2779 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2782 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2783 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2784 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2792 close(listener_pipe[0]);
2794 status = reinit_after_fork(smbd_messaging_context(),
2795 smbd_event_context(), false);
2796 if (!NT_STATUS_IS_OK(status)) {
2797 DEBUG(1, ("reinit_after_fork failed: %s\n",
2798 nt_errstr(status)));
2801 smbd_echo_loop(sconn, listener_pipe[1]);
2804 close(listener_pipe[1]);
2805 listener_pipe[1] = -1;
2806 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2808 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2811 * Without smb signing this is the same as the normal smbd
2812 * listener. This needs to change once signing comes in.
2814 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2816 sconn->smb1.echo_handler.trusted_fd,
2818 smbd_server_echo_handler,
2820 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2821 DEBUG(1, ("event_add_fd failed\n"));
2828 if (listener_pipe[0] != -1) {
2829 close(listener_pipe[0]);
2831 if (listener_pipe[1] != -1) {
2832 close(listener_pipe[1]);
2834 sconn->smb1.echo_handler.trusted_fd = -1;
2835 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2836 close(sconn->smb1.echo_handler.socket_lock_fd);
2838 sconn->smb1.echo_handler.trusted_fd = -1;
2839 sconn->smb1.echo_handler.socket_lock_fd = -1;
2843 /****************************************************************************
2844 Process commands from the client
2845 ****************************************************************************/
2847 void smbd_process(void)
2849 TALLOC_CTX *frame = talloc_stackframe();
2850 struct sockaddr_storage ss;
2851 struct sockaddr *sa = NULL;
2853 struct tsocket_address *local_address = NULL;
2854 struct tsocket_address *remote_address = NULL;
2855 const char *remaddr = NULL;
2858 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2859 lp_security() != SEC_SHARE &&
2860 !lp_async_smb_echo_handler()) {
2862 * We're not making the desion here,
2863 * we're just allowing the client
2864 * to decide between SMB1 and SMB2
2865 * with the first negprot
2868 smbd_server_conn->using_smb2 = true;
2871 /* Ensure child is set to blocking mode */
2872 set_blocking(smbd_server_fd(),True);
2874 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2875 set_socket_options(smbd_server_fd(), lp_socket_options());
2877 sa = (struct sockaddr *)(void *)&ss;
2878 sa_len = sizeof(ss);
2879 ret = getpeername(smbd_server_fd(), sa, &sa_len);
2881 int level = (errno == ENOTCONN)?2:0;
2882 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2883 exit_server("getpeername() failed.\n");
2885 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2889 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2890 __location__, strerror(errno)));
2891 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2894 sa = (struct sockaddr *)(void *)&ss;
2895 sa_len = sizeof(ss);
2896 ret = getsockname(smbd_server_fd(), sa, &sa_len);
2898 int level = (errno == ENOTCONN)?2:0;
2899 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2900 exit_server("getsockname() failed.\n");
2902 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2906 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2907 __location__, strerror(errno)));
2908 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2911 smbd_server_conn->local_address = local_address;
2912 smbd_server_conn->remote_address = remote_address;
2914 if (tsocket_address_is_inet(remote_address, "ip")) {
2915 remaddr = tsocket_address_inet_addr_string(
2916 smbd_server_conn->remote_address,
2918 if (remaddr == NULL) {
2922 remaddr = "0.0.0.0";
2925 /* this is needed so that we get decent entries
2926 in smbstatus for port 445 connects */
2927 set_remote_machine_name(remaddr, false);
2928 reload_services(true);
2931 * Before the first packet, check the global hosts allow/ hosts deny
2932 * parameters before doing any parsing of packets passed to us by the
2933 * client. This prevents attacks on our parsing code from hosts not in
2934 * the hosts allow list.
2937 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2938 lp_hostsdeny(-1))) {
2940 * send a negative session response "not listening on calling
2943 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2944 DEBUG( 1, ("Connection denied from %s to %s\n",
2945 tsocket_address_string(remote_address, talloc_tos()),
2946 tsocket_address_string(local_address, talloc_tos())));
2947 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2949 exit_server_cleanly("connection denied");
2952 DEBUG(10, ("Connection allowed from %s to %s\n",
2953 tsocket_address_string(remote_address, talloc_tos()),
2954 tsocket_address_string(local_address, talloc_tos())));
2960 smb_perfcount_init();
2962 if (!init_account_policy()) {
2963 exit_server("Could not open account policy tdb.\n");
2966 if (*lp_rootdir()) {
2967 if (chroot(lp_rootdir()) != 0) {
2968 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2969 exit_server("Failed to chroot()");
2971 if (chdir("/") == -1) {
2972 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2973 exit_server("Failed to chroot()");
2975 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2978 if (!srv_init_signing(smbd_server_conn)) {
2979 exit_server("Failed to init smb_signing");
2982 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2983 exit_server("Failed to fork echo handler");
2987 if (!init_oplocks(smbd_messaging_context()))
2988 exit_server("Failed to init oplocks");
2990 /* register our message handlers */
2991 messaging_register(smbd_messaging_context(), NULL,
2992 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2993 messaging_register(smbd_messaging_context(), NULL,
2994 MSG_SMB_RELEASE_IP, msg_release_ip);
2995 messaging_register(smbd_messaging_context(), NULL,
2996 MSG_SMB_CLOSE_FILE, msg_close_file);
2999 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3000 * MSGs to all child processes
3002 messaging_deregister(smbd_messaging_context(),
3004 messaging_register(smbd_messaging_context(), NULL,
3005 MSG_DEBUG, debug_message);
3007 if ((lp_keepalive() != 0)
3008 && !(event_add_idle(smbd_event_context(), NULL,
3009 timeval_set(lp_keepalive(), 0),
3010 "keepalive", keepalive_fn,
3012 DEBUG(0, ("Could not add keepalive event\n"));
3016 if (!(event_add_idle(smbd_event_context(), NULL,
3017 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3018 "deadtime", deadtime_fn, NULL))) {
3019 DEBUG(0, ("Could not add deadtime event\n"));
3023 if (!(event_add_idle(smbd_event_context(), NULL,
3024 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3025 "housekeeping", housekeeping_fn, NULL))) {
3026 DEBUG(0, ("Could not add housekeeping event\n"));
3030 #ifdef CLUSTER_SUPPORT
3032 if (lp_clustering()) {
3034 * We need to tell ctdb about our client's TCP
3035 * connection, so that for failover ctdbd can send
3036 * tickle acks, triggering a reconnection by the
3040 struct sockaddr_storage srv, clnt;
3042 if (client_get_tcp_info(&srv, &clnt) == 0) {
3046 status = ctdbd_register_ips(
3047 messaging_ctdbd_connection(),
3048 &srv, &clnt, release_ip, NULL);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3052 nt_errstr(status)));
3056 DEBUG(0,("Unable to get tcp info for "
3057 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3064 smbd_server_conn->nbt.got_session = false;
3066 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3068 smbd_server_conn->smb1.sessions.done_sesssetup = false;
3069 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
3070 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3071 /* users from session setup */
3072 smbd_server_conn->smb1.sessions.session_userlist = NULL;
3073 /* workgroup from session setup. */
3074 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
3075 /* this holds info on user ids that are already validated for this VC */
3076 smbd_server_conn->smb1.sessions.validated_users = NULL;
3077 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
3078 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
3080 conn_init(smbd_server_conn);
3081 if (!init_dptrs(smbd_server_conn)) {
3082 exit_server("init_dptrs() failed");
3085 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
3089 smbd_server_connection_handler,
3091 if (!smbd_server_conn->smb1.fde) {
3092 exit_server("failed to create smbd_server_connection fde");
3100 frame = talloc_stackframe_pool(8192);
3104 status = smbd_server_connection_loop_once(smbd_server_conn);
3105 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3106 !NT_STATUS_IS_OK(status)) {
3107 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3108 " exiting\n", nt_errstr(status)));
3115 exit_server_cleanly(NULL);
3118 bool req_is_in_chain(struct smb_request *req)
3120 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3122 * We're right now handling a subsequent request, so we must
3128 if (!is_andx_req(req->cmd)) {
3134 * Okay, an illegal request, but definitely not chained :-)
3139 return (CVAL(req->vwv+0, 0) != 0xFF);